You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试Android Binder以追踪struct binder_node引用计数变化?

观察Android Binder中struct binder_node引用计数变化的方法

一、用Binder驱动自带调试选项快速获取日志

Binder驱动内置了引用相关的调试开关,无需修改代码就能启用:

  • 启用引用计数调试日志:
    echo 0x10000 > /sys/module/binder/parameters/debug_mask
    
    这个掩码对应BINDER_DEBUG_REFS,会把struct binder_node的引用增减细节打印到dmesg,包括node指针、当前计数、调用触发点。
  • 查看当前调试掩码:cat /sys/module/binder/parameters/debug_mask,可以叠加0x20000(BINDER_DEBUG_TRANSACTION)掩码,关联交易过程和引用变化。
  • 内核代码路径:驱动中处理引用计数的核心函数是binder_inc_node和binder_dec_node,位于drivers/android/binder.c,启用BINDER_DEBUG_REFS后,这两个函数会通过binder_debug输出日志。

二、用ftrace追踪引用计数的触发流程

ftrace是内核原生追踪工具,能无侵入监控函数调用:

  1. 先挂载debugfs:mount -t debugfs none /sys/kernel/debug
  2. 基础函数追踪:
    cd /sys/kernel/debug/tracing
    echo function > current_tracer
    echo binder_inc_node,binder_dec_node > set_ftrace_filter
    echo 1 > tracing_on
    
    执行Binder操作后,cat trace就能看到每个函数调用的进程、调用栈,方便定位是哪个操作触发的引用变化。
  3. 进阶流程追踪:用funcgraph追踪器看完整调用链:
    echo funcgraph > current_tracer
    echo binder_inc_node,binder_dec_node > set_ftrace_filter
    echo 1 > tracing_on
    
    结果会展示调用这两个函数的上层逻辑,更清晰对应到具体Binder操作(比如跨进程传递Binder对象、释放对象)。

三、手动添加内核日志做深度调试

如果自带日志信息不足,可以临时修改内核代码添加自定义输出:

  • 打开drivers/android/binder.c,找到binder_inc_node和binder_dec_node函数,在计数修改前后添加日志:
    static void binder_inc_node(struct binder_node *node, int strong, int internal)
    {
        pr_info("binder_inc_node: node=%p, old_strong=%d, internal=%d\n",
                node, node->strong_refs, internal);
        // 原有函数逻辑
        pr_info("binder_inc_node: node=%p, new_strong=%d\n",
                node, node->strong_refs);
    }
    
  • 重新编译内核刷入设备,通过dmesg查看日志。注意用pr_debug的话,需要开启内核编译选项CONFIG_DEBUG_FS=y和CONFIG_DEBUG_KERNEL=y。

四、关键代码路径梳理

要验证引用计数逻辑正确性,重点关注这些核心逻辑:

  • binder_inc_node:负责增加引用计数,区分强引用(strong=1)和弱引用,内部调用binder_inc_ref更新计数。
  • binder_dec_node:负责减少引用计数,当强引用归零时会触发node销毁,内部调用binder_dec_ref。
  • 触发场景:跨进程传递Binder对象时调用binder_inc_node,进程退出、Binder对象释放或交易完成时调用binder_dec_node。
  • 计数存储:struct binder_node中的strong_refs(强引用)和weak_refs(弱引用)字段,对应不同的引用类型。

五、用perf统计调用次数做初步校验

perf可以统计函数调用频次,快速判断引用计数是否存在增减不匹配:

perf record -g -e 'binder:*inc_node' -e 'binder:*dec_node' sleep 10
perf report

这段命令会统计10秒内两个函数的调用次数,如果binder_inc_node次数远大于binder_dec_node,可能存在引用泄漏问题。

内容的提问来源于stack exchange,提问作者Cyb3rCr0wCC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 19:07:26