Binder 子系统之调试分析(二)

654 查看

一. 概述

上一篇文章已经介绍了binder子系统调试的一些手段,这篇文章再来挑选系统几个核心服务进程来进行分析.

1.1 创建debugfs

首先debugfs文件系统默认挂载在节点/sys/kernel/debug,binder驱动初始化的过程会在该节点下先创建/binder目录,然后在该目录下创建下面文件和目录:

  • proc/
  • stats
  • state
  • transactions
  • transaction_log
  • failed_transaction_log

比如:

另外,/d其实是指向/sys/kernel/debug的链接,也可以通过节点/d/binder来访问.

1.2 内核编译选项

如果系统关闭了debugfs,则通过编辑kernel/arch/arm/configs/×××_defconfig

二. stats

2.1 binder_stats

其中obj的个数由一个枚举变量binder_stat_types定义。

统计创建与删除的对象

binder_stat_types中定义的量:

类型 含义
BINDER_STAT_PROC binder进程
BINDER_STAT_THREAD binder线程
BINDER_STAT_NODE binder节点
BINDER_STAT_REF binder引用节
BINDER_STAT_DEATH binder死亡
BINDER_STAT_TRANSACTION binder事务
BINDER_STAT_TRANSACTION_COMPLETE binder已完成事务

每个类型相应的调用方法:

类型 创建调用 删除调用
BINDER_STAT_PROC binder_open binder_deferred_release
BINDER_STAT_THREAD binder_get_thread binder_free_thread
BINDER_STAT_NODE binder_new_node binder_thread_read/ binder_node_release/ binder_dec_node
BINDER_STAT_REF binder_get_ref_for_node binder_delete_ref
BINDER_STAT_DEATH binder_thread_write binder_thread_read/ binder_release_work/ binder_delete_ref
BINDER_STAT_TRANSACTION binder_transaction binder_thread_read/ binder_transaction/ binder_release_work/ binder_pop_transaction
BINDER_STAT_TRANSACTION_COMPLETE binder_transaction binder_thread_read/ binder_transaction/ binder_release_work

2.2 stats分析

执行上述语句,所对应的函数binder_stats_show,所输出结果分两部分:

  1. 整体统计信息
    • 所有BC_XXX命令的次数;
    • 所有BR_XXX命令的次数;
    • 输出binder_stat_types各个类型的active和total;
  2. 遍历所有进程的统计信息:
    • 当前进程相关的统计信息;
    • 所有BC_XXX命令的次数;
    • 所有BR_XXX命令的次数;

其中active是指当前系统存活的个数,total是指系统从开机到现在总共创建过的个数。下面举例来说明输出结果的含义:

2.2.1 整体统计信息

可知:

  • 当前系统binder_proc个数为78,binder_thread个数为530,binder_node为1753等信息;
  • 从开机到现在共创建过382个binder_proc,3196个binder_thread等;
  • transaction active等于零,目前没有活动的transaction事务

规律: BC_TRANSACTION + BC_REPLY = BR_TRANSACTION_COMPLETE + BR_DEAD_REPLY + BR_FAILED_REPLY

2.2.2 进程统计信息

可知进程14328:

  • 共有3个binder_thread,最大线程个数上限为15.
  • 共有3个binder_node, 9个binder_ref。
  • 已分配binder_buffer为零,异步可用空间约为520k;
  • proc->todo队列为空;

Debug Tips:

  • 当binder内存紧张时,可查看free async spacebuffers:字段;
  • 当系统空闲时,一般来说ready_threads = requested_threads_started +BC_ENTER_LOOPER; 当系统繁忙时ready_threads可能为0.
  • 例如system_server进程的ready_threads线程个数越少,系统可能处于越繁忙的状态;
  • 绝大多数的进程max_threads = 15,而surfaceflinger最大线程个数为4,servicemanager最大线程个数为0(只有主线程);

例如,想查看当前系统所有进程的异步可用内存情况,可执行:

2.3 其他

2.3.1 transactions

命令:

输出结果:

解释:

  • pid=20256进程,buffer的data_size=212,offsets_size=0,delivered代表已分发的内存块
  • 该命令遍历输出所有进程的情况,可以看出每个进程buffer的分发情况。

2.3.2 transaction_log

命令:

输出结果: