背景
上一篇文章
Binder通讯如何打印client调用堆栈即systrace查看对应方法
已经介绍了Binder调用相关的堆栈打印还有在systrace下面也有相关的调用发起的binder的方法名字打印。
但是同时也有学员朋友提出相关的疑问
客户端展示详细跨进程方法
com.android.internal.app.IAppOpsService
S
t
u
b
Stub
StubProxy.checkOperation
但是服务端没有看到有详细方法展示
正常应该是需要两端都有详细方法展示。
解决方法讲解
frameworks/base/core/java/android/os/Binder.java
private boolean execTransactInternal(int code, Parcel data, Parcel reply, int flags,
int callingUid) {
final boolean tagEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_AIDL);
final boolean tracingEnabled = tagEnabled && transactionTraceName != null;
try {
if (tracingEnabled) {
//这里有相关的traceBegin打印
Trace.traceBegin(Trace.TRACE_TAG_AIDL, transactionTraceName);
}
// TODO - this logic should not be in Java - it should be in native
// code in libbinder so that it works for all binder users. Further,
// this should not re-use flags.
if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0 && callingUid != -1) {
AppOpsManager.startNotedAppOpsCollection(callingUid);
try {
res = onTransact(code, data, reply, flags);
} finally {
AppOpsManager.finishNotedAppOpsCollection();
}
} else {
res = onTransact(code, data, reply, flags);
}
} catch (RemoteException|RuntimeException e) {
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_AIDL);
}
return res;
}
大家都知道服务端执行一般是onTransact开始,这里面也可以看到有了相关的trace打印到systrace,但是实际上我们并没有看到有相关的trace有打印。代码中也可以看出线索,这里的Trace打印输出的tag是Trace.TRACE_TAG_AIDL,要这个可以打印出来那么必须要Trace.TRACE_TAG_AIDL是开放的状态。
那么我们尝试抓取trace时候带上aidl参数试试:
抓取trace之后的结果如下:
果然发现这里服务端已经有了相关的跨进程详细方法
整体格式
AIDL::java::IAppOpsService::checkOperation::server
AIDL::java 即代表java类型的跨进程方法
IAppOpsService::checkOperation 代表具体服务端方法
server 代表服务端
这个trace打印同时也支持一些cpp端的打印
例如可以看下面:
上面就是apk应用进程发起跨进程调用ISurfaceComposer::createDisplayEventConnection
AIDL::cpp::ISurfaceComposer::createDisplayEventConnection::cppClient
AIDL::cpp::ISurfaceComposer::createDisplayEventConnection::cppServer
AIDL::cpp代表是cpp代码发起跨进程调用
ISurfaceComposer::createDisplayEventConnection 跨进程的具体方法
cppClient,cppServer代表跨进程客户端,服务端
相关trace输出TAG分析
这里可以看一下相关源码
大家可以看到这里其实也有相关注释说明这些名字的其实由aidl工具生成的
如果是cpp代码情况:
这里可以寻找到对的aidl生成的相关的文件:
比如寻找ISurfaceComposer.aidl文件生成的cpp
test@test:~/disk2/aosp14/out/soong/.intermediates/frameworks$ find -name ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_vendor.34_x86_x86_64_static/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_x86_x86_64_static_afdo-libgui_lto-thin/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_vendor.34_x86_64_static_afdo-libgui_lto-thin/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_vendor.34_x86_x86_64_static_afdo-libgui_lto-thin/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_x86_64_static_afdo-libgui_lto-thin/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_x86_64_static/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_x86_x86_64_static/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_x86_64_static_afdo-surfaceflinger_lto-thin/gen/aidl/android/gui/ISurfaceComposer.cpp
./native/libs/gui/libgui_aidl_static/android_vendor.34_x86_64_static/gen/aidl/android/gui/ISurfaceComposer.cpp
test@test:~/disk2/aosp14/out/soong/.intermediates/frameworks$ vi ./native/libs/gui/libgui_aidl_static/android_x86_64_static/gen/aidl/android/gui/ISurfaceComposer.cpp
总结
这里的systrace打印跨进程的方法,不是针对所有接口都有哈,一般针对aidl文件实现的接口才有,因为都是会通过aidl工具进行编译时候植入相关trace,本质上要systrace可以看到更多完整的aidl接口相关调用,需要以下两步:
1、adb shell am trace-ipc start
2、抓取perfetto时候偶带上tag为aidl
本文基础参考:
Binder通讯如何打印client调用堆栈即systrace查看对应方法
更多framework实战干货,请关注下面“千里马学框架”