Binder子系统之调试分析(二)
一. 概述
上一篇文章已經介紹了binder子系統調試的一些手段,這篇文章再來挑選系統幾個核心服務進程來進行分析.
1.1 創建debugfs
首先debugfs文件系統默認掛載在節點/sys/kernel/debug,binder驅動初始化的過程會在該節點下先創建/binder目錄,然后在該目錄下創建下面文件和目錄:
- proc/
- stats
- state
- transactions
- transaction_log
- failed_transaction_log
比如:
//創建目錄 /sys/kernel/debug/binder binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);//創建目錄 /sys/kernel/debug/binder/proc binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", binder_debugfs_dir_entry_root);//創建文件/sys/kernel/debug/binder/state debugfs_create_file("state",S_IRUGO, binder_debugfs_dir_entry_root, NULL, &binder_state_fops);另外,/d其實是指向/sys/kernel/debug的鏈接,也可以通過節點/d/binder來訪問.
1.2 內核編譯選項
如果系統關閉了debugfs,則通過編輯kernel/arch/arm/configs/×××_defconfig
//開啟debugfs CONFIG_DEBUG_FS=y //有時,可能還需要配置fs的白名單列表,例如: CONFIG_DEBUG_FS_WHITE_LIST=":/tracing:/binder:/wakeup_sources:"二. stats
2.1 binder_stats
struct binder_stats {int br[_IOC_NR(BR_FAILED_REPLY) + 1]; //統計各個binder響應碼的個數int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1]; //統計各個binder請求碼的個數int obj_created[BINDER_STAT_COUNT]; //統計各種obj的創建個數int obj_deleted[BINDER_STAT_COUNT]; //統計各種obj的刪除個數 };其中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分析
cat /d/binder/stats執行上述語句,所對應的函數binder_stats_show,所輸出結果分兩部分:
- 所有BC_XXX命令的次數;
- 所有BR_XXX命令的次數;
- 輸出binder_stat_types各個類型的active和total;
- 當前進程相關的統計信息;
- 所有BC_XXX命令的次數;
- 所有BR_XXX命令的次數;
其中active是指當前系統存活的個數,total是指系統從開機到現在總共創建過的個數。下面舉例來說明輸出結果的含義:
2.2.1 整體統計信息
binder stats: BC_TRANSACTION: 235258 BC_REPLY: 163048 BC_FREE_BUFFER: 397853 BC_INCREFS: 22573 BC_ACQUIRE: 22735 BC_RELEASE: 15840 BC_DECREFS: 15810 BC_INCREFS_DONE: 9517 BC_ACQUIRE_DONE: 9518 BC_REGISTER_LOOPER: 421 BC_ENTER_LOOPER: 284 BC_REQUEST_DEATH_NOTIFICATION: 4696 BC_CLEAR_DEATH_NOTIFICATION: 3707 BC_DEAD_BINDER_DONE: 400 BR_TRANSACTION: 235245 BR_REPLY: 163045 BR_DEAD_REPLY: 3 BR_TRANSACTION_COMPLETE: 398300 BR_INCREFS: 9517 BR_ACQUIRE: 9518 BR_RELEASE: 5448 BR_DECREFS: 5447 BR_SPAWN_LOOPER: 462 BR_DEAD_BINDER: 400 BR_CLEAR_DEATH_NOTIFICATION_DONE: 3707 BR_FAILED_REPLY: 3proc: active 78 total 382 thread: active 530 total 3196 node: active 1753 total 8134 ref: active 2604 total 13422 death: active 530 total 3991 transaction: active 0 total 195903 transaction_complete: active 0 total 195903可知:
- 當前系統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 進程統計信息
proc 14328threads: 3 //binder_thread個數//requested_threads(請求線程數) + requested_threads_started(已啟動線程數) / max_threads(最大線程數)requested threads: 0+1/15ready threads 2 // ready_threads(準備就緒的線程數)free async space 520192 //可用的異步空間約為520knodes: 3 //binder_node個數refs: 9 s 9 w 9 //引用次數,強引用次數,弱引用次數次數buffers: 0 //allocated_buffers(已分配的buffer個數)pending transactions: 0 //proc的todo隊列事務個數//該進程中BC_XXX 和BR_XXX命令執行次數BC_TRANSACTION: 21BC_FREE_BUFFER: 24BC_INCREFS: 9BC_ACQUIRE: 9BC_INCREFS_DONE: 3BC_ACQUIRE_DONE: 3BC_REGISTER_LOOPER: 1BC_ENTER_LOOPER: 1BC_REQUEST_DEATH_NOTIFICATION: 1BR_TRANSACTION: 4BR_REPLY: 20BR_TRANSACTION_COMPLETE: 21BR_INCREFS: 3BR_ACQUIRE: 3BR_SPAWN_LOOPER: 1可知進程14328:
- 共有3個binder_thread,最大線程個數上限為15.
- 共有3個binder_node, 9個binder_ref。
- 已分配binder_buffer為零,異步可用空間約為520k;
- proc->todo隊列為空;
Debug Tips:
- 當binder內存緊張時,可查看free async space和buffers:字段;
- 當系統空閑時,一般來說ready_threads?=?requested_threads_started?+BC_ENTER_LOOPER; 當系統繁忙時ready_threads可能為0.
- 例如system_server進程的ready_threads線程個數越少,系統可能處于越繁忙的狀態;
- 絕大多數的進程max_threads?= 15,而surfaceflinger最大線程個數為4,servicemanager最大線程個數為0(只有主線程);
例如,想查看當前系統所有進程的異步可用內存情況,可執行:
adb shell cat /d/binder/stats | egrep "proc |free async space"2.3 其他
2.3.1 transactions
命令:
cat /d/binder/transactions輸出結果:
binder transactions: proc 20256buffer 348035: ffffff800a280050 size 212:0 delivered ...解釋:
- pid=20256進程,buffer的data_size=212,offsets_size=0,delivered代表已分發的內存塊
- 該命令遍歷輸出所有進程的情況,可以看出每個進程buffer的分發情況。
2.3.2 transaction_log
命令:
cat /d/binder/transaction_log輸出結果:
357140: async from 8963:9594 to 10777:0 node 145081 handle 717 size 172:0 357141: call from 8963:9594 to 435:0 node 1 handle 0 size 80:0 357142: reply from 435:435 to 8963:9594 node 0 handle 0 size 24:8解釋:
debug_id:?call_type?from?from_proc:from_thread?to?to_proc:to_thread?node?to_nodehandle?target_handle?size?data_size:offsets_size
call_type:有3種,分別為async, call, reply.
transaction_log以及還有binder_transaction_log_failed會只會記錄最近的32次的transaction過程.
2.3.3 state
cat /d/binder/state執行上述語句,所對應的函數binder_state_show,輸出當前系統binder_proc, binder_node等信息;
2.3.4 proc
cat /d/binder/proc/<pid>可查看單獨每個進程更為詳細的信息,鎖對應的函數binder_proc_show
三、 trace_pipe
cd /d/tracing/events/binder進入該目錄,會看到有很多binder相關的節點,需要通過開關來控制是否開啟相應的調試開關。例如,要開啟binder_buffer內存分配過程的log:
echo 1 > /d/tracing/events/binder/binder_transaction_alloc_buf/enable查看信息:
cat /d/tracing/trace_pipe要關閉該信息:
echo 0 > /d/tracing/events/binder/binder_transaction_alloc_buf/enable當然也可以直接輸出到文件:
adb shell cat /d/tracing/trace_pipe > trace_binder這里可以開啟的信息有很多,再比如:
echo 1 > /d/tracing/events/binder/enable更多開關與功能,可自行探索。
原文地址:http://gityuan.com/2016/08/28/binder-debug-2/
總結
以上是生活随笔為你收集整理的Binder子系统之调试分析(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Binder子系统之调试分析(一)
- 下一篇: Binder子系统之调试分析(三)