目录
一,打开开关
二,打开 signal trace:
三,设置缓冲大小
四,执行 cat /sys/kernel/debug/tracing/tracing_on
echo 1 >/sys/kernel/debug/tracing/tracing_on
这一步很重要,不然在使用cat /sys/kernel/debug/tracing/trace命令的时候看不到具体的调用过程
二,打开 signal trace:
echo 1 > /sys/kernel/debug/tracing/events/signal/enable
echo 1 > /sys/kernel/debug/tracing/tracing_on
三,设置缓冲大小
cat /sys/kernel/debug/tracing/buffer_size_kb
1410
# cat /sys/kernel/debug/tracing/buffer_total_size_kb
11280
echo 2048 > /sys/kernel/debug/tracing/buffer_size_kb
cat /sys/kernel/debug/tracing/buffer_size_kb
2048
cat /sys/kernel/debug/tracing/buffer_total_size_kb
16384
四,执行 cat /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/tracing_on
0
angler:/sys/kernel/debug/binder/proc # echo 1 >/sys/kernel/debug/tracing/tracing_on
angler:/sys/kernel/debug/binder/proc #
angler:/sys/kernel/debug/binder/proc #
angler:/sys/kernel/debug/binder/proc # cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 18446744073709507068/142 #P:8
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
WifiStateMachin-30921 [000] ...1 61849.807864: binder_ioctl: cmd=0xc0306201 arg=0x7c4979a6b8
WifiStateMachin-30921 [000] ...1 61849.807881: binder_lock: tag=binder_ioctl
WifiStateMachin-30921 [000] ...2 61849.807886: binder_locked: tag=binder_ioctl
WifiStateMachin-30921 [000] ...2 61849.807895: binder_command: cmd=0x40086303 BC_FREE_BUFFER
WifiStateMachin-30921 [000] ...2 61849.807905: binder_transaction_buffer_release: transaction=18255975 data_size=204 offsets_size=32
WifiStateMachin-30921 [000] ...2 61849.807921: binder_command: cmd=0x40486311 BC_TRANSACTION_SG
WifiStateMachin-30921 [000] ...2 61849.807939: binder_transaction: transaction=18255978 dest_node=423193 dest_proc=418 dest_thread=0 reply=0 flags=0x10 code=0xd
WifiStateMachin-30921 [000] ...2 61849.807948: binder_transaction_alloc_buf: transaction=18255978 data_size=44 offsets_size=0
WifiStateMachin-30921 [000] ...2 61849.807988: binder_write_done: ret=0
WifiStateMachin-30921 [000] ...2 61849.807994: binder_unlock: tag=binder_thread_read
WifiStateMachin-30921 [000] ...1 61849.807998: binder_wait_for_work: proc_work=0 transaction_stack=1 thread_todo=1
WifiStateMachin-30921 [000] ...1 61849.808003: binder_lock: tag=binder_thread_read
WifiStateMachin-30921 [000] ...2 61849.808007: binder_locked: tag=binder_thread_read
WifiStateMachin-30921 [000] ...2 61849.808012: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
WifiStateMachin-30921 [000] ...2 61849.808019: binder_read_done: ret=0
WifiStateMachin-30921 [000] ...2 61849.808024: binder_unlock: tag=binder_ioctl
WifiStateMachin-30921 [000] ...1 61849.808028: binder_ioctl_done: ret=0
WifiStateMachin-30921 [000] ...1 61849.808050: binder_ioctl: cmd=0xc0306201 arg=0x7c4979a6b8
WifiStateMachin-30921 [000] ...1 61849.808054: binder_lock: tag=binder_ioctl
WifiStateMachin-30921 [000] ...2 61849.808057: binder_locked: tag=binder_ioctl
WifiStateMachin-30921 [000] ...2 61849.808062: binder_unlock: tag=binder_thread_read
WifiStateMachin-30921 [000] ...1 61849.808066: binder_wait_for_work: proc_work=0 transaction_stack=1 thread_todo=0
android.hardwar-418 [000] ...1 61849.808135: binder_lock: tag=binder_thread_read
android.hardwar-418 [000] ...2 61849.808139: binder_locked: tag=binder_thread_read
android.hardwar-418 [000] ...2 61849.808150: binder_transaction_received: transaction=18255978
android.hardwar-418 [000] ...2 61849.808154: binder_return: cmd=0x80407202 BR_TRANSACTION
android.hardwar-418 [000] ...2 61849.808159: binder_read_done: ret=0
android.hardwar-418 [000] ...2 61849.808165: binder_unlock: tag=binder_ioctl
android.hardwar-418 [000] ...1 61849.808169: binder_ioctl_done: ret=0
android.hardwar-418 [000] ...1 61849.812233: binder_ioctl: cmd=0xc0306201 arg=0x7ffe4a3a38
android.hardwar-418 [000] ...1 61849.812251: binder_lock: tag=binder_ioctl
android.hardwar-418 [000] ...2 61849.812256: binder_locked: tag=binder_ioctl
android.hardwar-418 [000] ...2 61849.812265: binder_command: cmd=0x40486312 BC_REPLY_SG
android.hardwar-418 [000] ...2 61849.812284: binder_transaction: transaction=18255979 dest_node=0 dest_proc=30833 dest_thread=30921 reply=1 flags=0x0 code=0x0
android.hardwar-418 [000] ...2 61849.812299: binder_transaction_alloc_buf: transaction=18255979 data_size=204 offsets_size=32
android.hardwar-418 [000] ...2 61849.812343: binder_write_done: ret=0
android.hardwar-418 [000] ...2 61849.812348: binder_unlock: tag=binder_thread_read
android.hardwar-418 [000] ...1 61849.812353: binder_wait_for_work: proc_work=0 transaction_stack=0 thread_todo=1
android.hardwar-418 [000] ...1 61849.812358: binder_lock: tag=binder_thread_read
android.hardwar-418 [000] ...2 61849.812362: binder_locked: tag=binder_thread_read
android.hardwar-418 [000] ...2 61849.812367: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
android.hardwar-418 [000] ...2 61849.812376: binder_read_done: ret=0
android.hardwar-418 [000] ...2 61849.812381: binder_unlock: tag=binder_ioctl
android.hardwar-418 [000] ...1 61849.812385: binder_ioctl_done: ret=0
android.hardwar-418 [000] ...1 61849.812467: binder_ioctl: cmd=0xc0306201 arg=0x7ffe4a4838
android.hardwar-418 [000] ...1 61849.812472: binder_lock: tag=binder_ioctl
android.hardwar-418 [000] ...2 61849.812475: binder_locked: tag=binder_ioctl
android.hardwar-418 [000] ...2 61849.812480: binder_command: cmd=0x40086303 BC_FREE_BUFFER
android.hardwar-418 [000] ...2 61849.812489: binder_transaction_buffer_release: transaction=18255978 data_size=44 offsets_size=0
android.hardwar-418 [000] ...2 61849.812500: binder_write_done: ret=0
android.hardwar-418 [000] ...2 61849.812504: binder_unlock: tag=binder_thread_read
android.hardwar-418 [000] ...1 61849.812508: binder_wait_for_work: proc_work=1 transaction_stack=0 thread_todo=0
WifiStateMachin-30921 [000] ...1 61849.813029: binder_lock: tag=binder_thread_read
WifiStateMachin-30921 [000] ...2 61849.813034: binder_locked: tag=binder_thread_read
WifiStateMachin-30921 [000] ...2 61849.813042: binder_transaction_received: transaction=18255979
WifiStateMachin-30921 [000] ...2 61849.813046: binder_return: cmd=0x80407203 BR_REPLY
WifiStateMachin-30921 [000] ...2 61849.813054: binder_read_done: ret=0
WifiStateMachin-30921 [000] ...2 61849.813059: binder_unlock: tag=binder_ioctl
WifiStateMachin-30921 [000] ...1 61849.813063: binder_ioctl_done: ret=0
##### CPU 1 buffer started ####
WifiStateMachin-30921 [001] ...1 61849.817312: binder_ioctl: cmd=0xc0306201 arg=0x7c4979a408
WifiStateMachin-30921 [001] ...1 61849.817331: binder_lock: tag=binder_ioctl
WifiStateMachin-30921 [001] ...2 61849.817337: binder_locked: tag=binder_ioctl
WifiStateMachin-30921 [001] ...2 61849.817348: binder_command: cmd=0x40406300 BC_TRANSACTION
WifiStateMachin-30921 [001] ...2 61849.817379: binder_transaction: transaction=18255980 dest_node=423405 dest_proc=30660 dest_thread=0 reply=0 flags=0x10 code=0x4
WifiStateMachin-30921 [001] ...2 61849.817390: binder_transaction_alloc_buf: transaction=18255980 data_size=76 offsets_size=0
WifiStateMachin-30921 [001] ...2 61849.817441: binder_write_done: ret=0
WifiStateMachin-30921 [001] ...2 61849.817446: binder_unlock: tag=binder_thread_read
WifiStateMachin-30921 [001] ...1 61849.817451: binder_wait_for_work: proc_work=0 transaction_stack=1 thread_todo=1
WifiStateMachin-30921 [001] ...1 61849.817455: binder_lock: tag=binder_thread_read
WifiStateMachin-30921 [001] ...2 61849.817459: binder_locked: tag=binder_thread_read
WifiStateMachin-30921 [001] ...2 61849.817465: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
WifiStateMachin-30921 [001] ...2 61849.817472: binder_read_done: ret=0
WifiStateMachin-30921 [001] ...2 61849.817477: binder_unlock: tag=binder_ioctl
WifiStateMachin-30921 [001] ...1 61849.817482: binder_ioctl_done: ret=0
wificond-30660 [000] ...1 61849.817495: binder_lock: tag=binder_poll
wificond-30660 [000] ...2 61849.817504: binder_locked: tag=binder_poll
WifiStateMachin-30921 [001] ...1 61849.817505: binder_ioctl: cmd=0xc0306201 arg=0x7c4979a408
WifiStateMachin-30921 [001] ...1 61849.817509: binder_lock: tag=binder_ioctl
wificond-30660 [000] ...2 61849.817509: binder_unlock: tag=binder_pol
jian.aidlserver-4838 [004] ...2 241.715269: binder_update_page_range: proc=4838 allocate=1 offset=0 size=4096
Binder:4838_1-4850 [006] ...1 241.716477: binder_ioctl: cmd=0xc0306201 arg=0x7d3a3872b8
Binder:4838_1-4850 [006] ...1 241.716479: binder_lock: tag=binder_ioctl
Binder:4838_1-4850 [006] ...2 241.716480: binder_locked: tag=binder_ioctl
Binder:4838_1-4850 [006] ...2 241.716482: binder_command: cmd=0x630c BC_ENTER_LOOPER
Binder:4838_1-4850 [006] ...2 241.716483: binder_write_done: ret=0
Binder:4838_1-4850 [006] ...2 241.716484: binder_unlock: tag=binder_thread_read
Binder:4838_1-4850 [006] ...1 241.716485: binder_wait_for_work: proc_work=1 transaction_stack=0 thread_todo=0
Binder:4838_1-4850 [006] ...1 241.716486: binder_lock: tag=binder_thread_read
Binder:4838_1-4850 [006] ...2 241.716487: binder_locked: tag=binder_thread_read
Binder:4838_1-4850 [006] ...2 241.716488: binder_return: cmd=0x720d BR_SPAWN_LOOPER
Binder:4838_1-4850 [006] ...2 241.716489: binder_read_done: ret=0
Binder:4838_1-4850 [006] ...2 241.716490: binder_unlock: tag=binder_ioctl
Binder:4838_1-4850 [006] ...1 241.716490: binder_ioctl_done: ret=0
重点看下这块在我打开一个进程以后,内存映射的只有4096大小
从这里可以反推源码
4.1 进程首次启动和binder通信
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
binder_write_read bwr;
// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
if (outAvail != 0) {
alog << "Sending commands to driver: " << indent;
const void* cmds = (const void*)bwr.write_buffer;
const void* end = ((const uint8_t*)cmds)+bwr.write_size;
alog << HexDump(cmds, bwr.write_size) << endl;
while (cmds < end) cmds = printCommand(alog, cmds);
alog << dedent;
}
alog << "Size of receive buffer: " << bwr.read_size
<< ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
IF_LOG_COMMANDS() {
alog << "About to read/write, write size = " << mOut.dataSize() << endl;
}
#if defined(__ANDROID__)
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
IF_LOG_COMMANDS() {
alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
}
} while (err == -EINTR);
IF_LOG_COMMANDS() {
alog << "Our err: " << (void*)(intptr_t)err << ", write consumed: "
<< bwr.write_consumed << " (of " << mOut.dataSize()
<< "), read consumed: " << bwr.read_consumed << endl;
}
if (err >= NO_ERROR) {
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
}
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
alog << "Remaining data size: " << mOut.dataSize() << endl;
alog << "Received commands from driver: " << indent;
const void* cmds = mIn.data();
const void* end = mIn.data() + mIn.dataSize();
alog << HexDump(cmds, mIn.dataSize()) << endl;
while (cmds < end) cmds = printReturnCommand(alog, cmds);
alog << dedent;
}
return NO_ERROR;
}
return err;
}
上面代码最核心的部分是首次创建进服务程的时候,只有写数据,通过ioctl给Binder驱动发送
cmd = BINDER_WRITE_READ的时候,会进入binder_thread_write函数
在binder_thread_write收到cmd = BC_ENTER_LOOPER的时候,驱动内部的线程会进入loop状态,
之后第二次在此执行cmd = BINDER_WRITE_READ的时候,此时的readSize就不是0,所以此时在binder驱动里面进入了binder_thread_read函数,在这里如果todo队列里面没有数据的话,此时就会binder_thread_read线程就会等待知道被唤醒,那什么时候被唤醒呢
4.2 没有数据的时候进程等待
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
{
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size;
int ret = 0;
int wait_for_proc_work;
if (*consumed == 0) {
if (put_user_preempt_disabled(BR_NOOP, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
}
retry:
wait_for_proc_work = thread->transaction_stack == NULL &&
list_empty(&thread->todo);
if (thread->return_error != BR_OK && ptr < end) {
if (thread->return_error2 != BR_OK) {
if (put_user_preempt_disabled(thread->return_error2, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
binder_stat_br(proc, thread, thread->return_error2);
if (ptr == end)
goto done;
thread->return_error2 = BR_OK;
}
if (put_user_preempt_disabled(thread->return_error, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
binder_stat_br(proc, thread, thread->return_error);
thread->return_error = BR_OK;
goto done;
}
thread->looper |= BINDER_LOOPER_STATE_WAITING;
if (wait_for_proc_work)
proc->ready_threads++;
binder_unlock(__func__);
trace_binder_wait_for_work(wait_for_proc_work,
!!thread->transaction_stack,
!list_empty(&thread->todo));
if (wait_for_proc_work) {
if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
BINDER_LOOPER_STATE_ENTERED))) {
binder_user_error("%d:%d ERROR: Thread waiting for process work before calling BC_REGISTER_LOOPER or BC_ENTER_LOOPER (state %x)\n",
proc->pid, thread->pid, thread->looper);
wait_event_interruptible(binder_user_error_wait,
binder_stop_on_user_error < 2);
}
binder_set_nice(proc->default_priority);
if (non_block) {
if (!binder_has_proc_work(proc, thread))
ret = -EAGAIN;
} else
ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
} else {
if (non_block) {
if (!binder_has_thread_work(thread))
ret = -EAGAIN;
} else
ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
}
-------------------------------------------
}
4.3 有数据的时候唤醒目标进程
1)在binder_ioctl里面收到读数据的时候,todo队列不为空,
if (bwr.read_size > 0) {
ret = binder_thread_read(proc, thread, bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
trace_binder_read_done(ret);
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait);
if (ret < 0) {
if (copy_to_user_preempt_disabled(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
2) binder_transaction
t->work.type = BINDER_WORK_TRANSACTION;
list_add_tail(&t->work.entry, target_list);
tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
list_add_tail(&tcomplete->entry, &thread->todo);
if (target_wait) {
if (reply || !(t->flags & TF_ONE_WAY)) {
wake_up_interruptible_sync(target_wait);
}
else {
wake_up_interruptible(target_wait);
}
}
return;
五,详细的命令
按照这个顺序执行
echo 1 > /sys/kernel/debug/tracing/events/signal/enable
echo 1 > /sys/kernel/debug/tracing/tracing_on
echo 1 > /sys/kernel/debug/tracing/events/binder/enable
cat /sys/kernel/debug/tracing/set_event
cat /sys/kernel/debug/tracing/trace