参考link:
http://gityuan.com/2016/09/04/binder-start-service/ //彻底理解Android Binder通信架构
http://gityuan.com/2018/02/17/monkey-deadlock/ //跑monkey压力测试过程的冻屏案例
1.发起端线程向Binder Driver发起binder ioctl请求后, 便采用环不断talkWithDriver,此时该线程处于阻塞状态, 直到收到如下BR_XXX命令才会结束该过程.
BR_TRANSACTION_COMPLETE: oneway模式下,收到该命令则退出
BR_REPLY: 非oneway模式下,收到该命令才退出;
BR_DEAD_REPLY: 目标进程/线程/binder实体为空, 以及释放正在等待reply的binder thread或者binder buffer;
BR_FAILED_REPLY: 情况较多,比如非法handle, 错误事务栈, security, 内存不足, buffer不足, 数据拷贝失败, 节点创建失败, 各种不匹配等问题
BR_ACQUIRE_RESULT: 目前未使用的协议;
2.左图中waitForResponse收到BR_TRANSACTION_COMPLETE,则直接退出循环, 则没有机会执行executeCommand()方法, 故将其颜色画为灰色. 除以上5种BR_XXX命令, 当收到其他BR命令,则都会执行executeCommand过程.
3.目标Binder线程创建后, 便进入joinThreadPool()方法, 采用循环不断地循环执行getAndExecuteCommand()方法, 当bwr的读写buffer都没有数据时,则阻塞在binder_thread_read的wait_event过程. 另外,正常情况下binder线程一旦创建则不会退出.
上图是非oneway通信过程的协议图, 下图则是对于oneway场景下的通信协议图:
//binder client java log (BinderProxy.transact) ,native log(IPCThreadState15waitForResponse) ,kernel log (kernel: binder_ioctl_write_read)
"Binder:1930_5" prio=5 tid=85 Native
| group="main" sCount=1 dsCount=0 obj=0x13cb1820 self=0x7f79fcd400
| sysTid=5316 nice=-2 cgrp=default sched=0/0 handle=0x7f6e1ff450
| state=S schedstat=( 0 0 0 ) utm=83 stm=56 core=2 HZ=100
| stack=0x7f6e105000-0x7f6e107000 stackSize=1005KB
| held mutexes=
kernel: __switch_to+0x88/0x94
kernel: binder_thread_read+0x4e4/0x1140 //binder driver log
kernel: binder_ioctl_write_read+0x1e0/0x31c
kernel: binder_ioctl+0x28c/0x710
kernel: do_vfs_ioctl+0x48c/0x564
kernel: SyS_ioctl+0x60/0x88
kernel: el0_svc_naked+0x24/0x28
native: #00 pc 000000000007831c /system/lib64/libc.so (__ioctl+4)
native: #01 pc 0000000000020020 /system/lib64/libc.so (ioctl+140)
native: #02 pc 0000000000055b14 /system/lib64/libbinder.so (_ZN7android14IPCThreadState14talkWithDriverEb+256) //binder native log
native: #03 pc 0000000000056ab8 /system/lib64/libbinder.so (_ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi+708)
native: #04 pc 000000000004b504 /system/lib64/libbinder.so (_ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j+72)
native: #05 pc 00000000000ff69c /system/lib64/libandroid_runtime.so (???)
native: #06 pc 0000000001117058 /data/dalvik-cache/arm64/system@[email protected] (Java_android_os_BinderProxy_transactNative__ILandroid_os_Parcel_2Landroid_os_Parcel_2I+196)
at android.os.BinderProxy.transactNative(Native method)
at android.os.BinderProxy.transact(Binder.java:615) //binder java log
at android.app.IActivityController$Stub$Proxy.appCrashed(IActivityController.java:222)
at com.android.server.am.AppErrors.handleAppCrashInActivityController(AppErrors.java:450)
at com.android.server.am.AppErrors.crashApplicationInner(AppErrors.java:334)
- locked <0x098877e9> (a com.android.server.am.ActivityManagerService)
at com.android.server.am.AppErrors.crashApplication(AppErrors.java:309)
at com.android.server.am.ActivityManagerService.handleApplicationCrashInner(ActivityManagerService.java:13799)
at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:13781)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:1646)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2886)
at android.os.Binder.execTransact(Binder.java:565)
//binder server onTransact
"Binder:17922_1" prio=5 tid=8 Blocked
| group="main" sCount=1 dsCount=0 obj=0x12c69940 self=0x7f97e12400
| sysTid=17961 nice=-2 cgrp=default sched=0/0 handle=0x7f96286450
| state=S schedstat=( 0 0 0 ) utm=0 stm=0 core=4 HZ=100
| stack=0x7f9618c000-0x7f9618e000 stackSize=1005KB
| held mutexes=
at com.android.commands.monkey.Monkey$ActivityController.appCrashed(Monkey.java:306)
- waiting to lock <0x0b9d2b64> (a com.android.commands.monkey.Monkey) held by thread 1
at android.app.IActivityController$Stub.onTransact(IActivityController.java:92)
at android.os.Binder.execTransact(Binder.java:565)