am trace-ipc使用小技巧之Binder服务端方法systrace打印剖析

背景

上一篇文章

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实战干货,请关注下面“千里马学框架”

Android 中,启动应用组件通常使用 `am`(Activity Manager)命令,它允许通过命令行控制 Activity、Service、BroadcastReceiver 等组件的启动和行为。`am` 命令支持多种参数,适用于不同的组件类型和启动模式。 ### `am start` 命令的基本语法 ```bash am start [options] <INTENT> ``` 其中 `<INTENT>` 通常由组件名称(`-n`)或动作(`-a`)以及数据(`-d`)等构成。 ### 启动 Activity 要启动一个特定的 Activity,可以使用以下命令: ```bash am start -n com.example.app/.MainActivity ``` 如果需要传递额外的数据,可以使用 `-e` 参数: ```bash am start -n com.example.app/.MainActivity --es "key" "value" ``` 其中 `--es` 表示传递字符串类型的额外数据。 ### 启动 Service 要启动一个 Service,可以使用 `-S` 参数来确保在启动前停止已运行的 Service: ```bash am start-service -n com.example.app/.MyService ``` 如果需要传递数据,同样可以使用 `-e` 系列参数: ```bash am start-service -n com.example.app/.MyService --ei "count" 5 ``` 其中 `--ei` 表示传递整型数据。 ### 发送 Broadcast 要发送一个广播,可以使用 `broadcast` 子命令: ```bash am broadcast -a com.example.app.MY_ACTION --es "data" "test" ``` 这将触发所有注册了 `com.example.app.MY_ACTION` 动作的 BroadcastReceiver。 ### 使用 `--ipc` 参数 `am` 命令本身并没有直接的 `--ipc` 参数。然而,Android 中的 IPC 通信主要通过 Binder 实现,而 `am` 命令在底层通过 Binder 机制与系统服务进行通信。例如,`BpBinder` 类用于客户端与 Binder 驱动进行交互,其 `transact` 方法负责发送事务请求[^2]。 ### 示例:启动 Activity 并传递多种类型的数据 ```bash am start -n com.example.app/.MainActivity \ --es "stringExtra" "Hello" \ --ei "intExtra" 42 \ --ez "booleanExtra" true \ --el "longExtra" 1234567890 \ --ef "floatExtra" 3.14 ``` ### 相关选项说明 - `-n`:指定组件名称,格式为 `<PACKAGE>/<CLASS>`。 - `-a`:指定 Intent 的动作(Action)。 - `-d`:指定 Intent 的数据(Data)。 - `-t`:指定数据的 MIME 类型。 - `-c`:添加 Category。 - `--es`:添加字符串类型的 Extra。 - `--ei`:添加整型的 Extra。 - `--ez`:添加布尔型的 Extra。 - `--el`:添加长整型的 Extra。 - `--ef`:添加浮点型的 Extra。 ### 注意事项 - 使用 `am` 命令时,确保设备已连接并处于调试模式。 - 权限问题:某些组件可能需要特定的权限才能启动。 - 如果目标组件未在 `AndroidManifest.xml` 中声明,启动可能会失败。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值