binder子系統之除錯分析2
一. 節點建立
上一篇文章已經介紹了binder子系統除錯的一些手段,這篇文章再來挑選系統幾個核心服務程序來進行分析.
1.1 核心編譯選項
如果系統關閉了debugfs,則通過編輯kernel/arch/arm/configs/×××_defconfig
//開啟debugfs
CONFIG_DEBUG_FS=y
//有時,可能還需要配置fs的白名單列表,例如:
CONFIG_DEBUG_FS_WHITE_LIST=":/tracing:/binder:/wakeup_sources:"
1.2 建立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
來訪問.
二. 節點分析
接下來,看看系統建立的以下5個節點:
/d/binder/stats (整體以及各個程序的執行緒數,事務個數等的統計資訊)
/d/binder/state (整體以及各個程序的thread/node/ref/buffer的狀態資訊)
/d/binder/failed_transaction_log (記錄32條最近的傳輸失敗事件)
/d/binder/transaction_log (記錄32 條最近的傳輸事件)
/d/binder/transactions (遍歷所有程序的buffer分配情況)
每個節點所相應的Binder驅動中的輸出函式為binder_xxx_show. 例如/d/binder/stats的節點資訊,所對應的輸出函式binder_stats_show.
2.1 stats
cat /d/binder/stats
執行上述語句,所對應的函式binder_stats_show
,所輸出結果分兩部分:
- 整體統計資訊
- 所有BC_XXX命令的次數;
- 所有BR_XXX命令的次數;
- 輸出
binder_stat_types
各個型別的active和total;
- 遍歷所有程序的統計資訊:
- 當前程序相關的統計資訊;
- 所有BC_XXX命令的次數;
- 所有BR_XXX命令的次數;
其中active是指當前系統存活的個數,total是指系統從開機到現在總共建立過的個數。下面舉例來說明輸出結果的含義:
2.1.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: 3
proc: 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
為什麼是會是這樣呢,因為每次BC_TRANSACTION或著BC_REPLY,都是有相應的BR_TRANSACTION_COMPLETE,在傳輸不出異常的情況下這個次數是相等,有時候並能transaction成功, 所以還需要加上BR_DEAD_REPLY和BR_FAILED_REPLY的情況.
2.1.2 各程序資訊
proc 14328
threads: 3 //binder_thread個數
//requested_threads(請求執行緒數) + requested_threads_started(已啟動執行緒數) / max_threads(最大執行緒數)
requested threads: 0+1/15
ready threads 2 // ready_threads(準備就緒的執行緒數)
free async space 520192 //可用的非同步空間約為520k
nodes: 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: 21
BC_FREE_BUFFER: 24
BC_INCREFS: 9
BC_ACQUIRE: 9
BC_INCREFS_DONE: 3
BC_ACQUIRE_DONE: 3
BC_REGISTER_LOOPER: 1
BC_ENTER_LOOPER: 1
BC_REQUEST_DEATH_NOTIFICATION: 1
BR_TRANSACTION: 4
BR_REPLY: 20
BR_TRANSACTION_COMPLETE: 21
BR_INCREFS: 3
BR_ACQUIRE: 3
BR_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(只有主執行緒); pending transactions
:是指該程序的todo佇列事務個數
例如,想檢視當前系統所有程序的非同步可用記憶體情況,可執行:
adb shell cat /d/binder/stats | egrep "proc |free async space"
相關說明
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 state
cat /d/binder/state
執行上述語句,所對應的函式binder_state_show
,輸出當前系統binder_proc, binder_node等資訊;
2.2.1 整體資訊
輸出所有死亡節點的資訊
dead nodes:
node 24713573: u0000007f9fe0c6c0 c0000007f9fe63700 hs 1 hw 1 ls 0 lw 0 is 1 iw 1 proc 12396
node 24712275: u0000007f9d5f0a80 c0000007fa82d1880 hs 1 hw 1 ls 0 lw 0 is 1 iw 1 proc 12396
2.2.2 各程序資訊
proc 18650
thread 18650: l 00
thread 18658: l 00
thread 18663: l 12
thread 18665: l 11
node 24805986: u00000000e153f070 c00000000e197dd80 hs 1 hw 1 ls 0 lw 0 is 1 iw 1 proc 12396
node 24805990: u00000000e153f090 c00000000e197dda0 hs 1 hw 1 ls 0 lw 0 is 1 iw 1 proc 12396
ref 24804528: desc 0 node 1 s 1 w 1 d 0000000000000000
ref 24804531: desc 1 node 24532956 s 1 w 1 d 0000000000000000
buffer 24805817: ffffff8018e00050 size 1896:0 delivered
buffer 24806788: ffffff8018e00808 size 152:0 delivered
遍歷程序的thread/node/ref/buffer資訊. 當然如果存在,還會有pending transaction資訊.
Tips:
- pending transaction: 記錄當前所有程序和執行緒 TODO佇列的transaction.
- outgoing transaction: 當前執行緒transaction_stack, 由該執行緒發出的事務;
- incoming transaction: 當前執行緒transaction_stack, 由需要執行緒接收的事務;
- pending transactions: 記錄當前程序總的pending事務;
2.2.3 proc
cat /d/binder/proc/<pid>
可檢視單獨每個程序更為詳細的資訊,鎖對應的函式binder_proc_show
. 這個等價於小節[2.2.2]的內容.
2.3 transactions
2.3.1 各程序資訊
binder transactions:
proc 20256
buffer 348035: ffffff800a280050 size 212:0 delivered
...
解釋:
- pid=20256程序,buffer的data_size=212,offsets_size=0,delivered代表已分發的記憶體塊
- 該命令遍歷輸出所有程序的情況,可以看出每個程序buffer的分發情況。
其實, [小節2.2] state的資訊是[小節2.3]的超集, 擁有比這個更為全面, 詳細的資訊. 比如binder_ref資訊只在state裡面才有.
2.4 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
相關推薦
binder子系統之除錯分析2
一. 節點建立上一篇文章已經介紹了binder子系統除錯的一些手段,這篇文章再來挑選系統幾個核心服務程序來進行分析.1.1 核心編譯選項如果系統關閉了debugfs,則通過編輯kernel/arch/arm/configs/×××_defconfig//開啟debugfs C
binder驅動-------之資料結構篇2
1:binder實體在驅動中的表示(struct binder_node ) binder_node是應用空間的binder實體在核心的表示,它直屬於某個特定的程序(binder_proc),其他程序對該binder實體的使用,都會掛在該binder實體的refs雜湊列表中
openstack之網路分析2
neutron如何讓tap和虛擬機器建立聯絡? 這幾天的收穫是,看日誌不僅要分析控制節點的日誌,還要分析物理節點的日誌。而且物理節點和虛擬機器的相關性更大一點。從物理節點的neutron日誌分析中可以得到更多答案。 這些是刪除虛擬機器時日誌中出現的部分命令 ['sudo'
HDFS源碼分析之NameNode(2)————Format
return exceptio 數據信息 row oid creat tail 進行 alt 在Hadoop的HDFS部署好了之後並不能馬上使用,而是先要對配置的文件系統進行格式化。在這裏要註意兩個概念,一個是文件系統,此時的文件系統在物理上還不存在,或許是網絡磁盤來
GCC編譯器原理(三)------編譯原理三:編譯過程(2-2)---編譯之語法分析
tails 需要 表達式 一個數 就是 out 和數 margin 操作符 2.2 語法分析 語法分析器(Grammar Parser)將對由掃描器產生的記號進行語法分析,從而產生語法樹(Syntax Tree)。整個分析過程采用了上下文無關語法(Context-free
QTrace--Android系統除錯分析的利器(2)
LogCat指令碼分析 QTrace為了方便指令碼處理,提供瞭如下幾個基礎功能: 1)QTrace將所有的log是放在資料庫中的,這樣查詢速度很快,並且可以按照不同的欄位進行查詢。 2)QTrace提供了資料圖形化顯示的基礎框架。可以方便的將資料圖形化。 3)QTrace的指令碼有介
BLE-CC254x-1.4.2.2之LCD分析
INT_HEAP_LEN=3072HALNODEBUGOSAL_CBTIMER_NUM_TASKS=1HAL_AES_DMA=TRUEHAL_DMA=TRUEPOWER_SAVINGxPLUS_BROADCASTERHAL_LCD=TRUEHAL_LED=FALSEHAL_KEY=TRUE
RocketMQ原始碼分析(一)之除錯環境搭建
版本宣告 基於rocketmq-all-4.3.1版本 所有分析是根據自己的理解,因為不是RocketMQ的原始開發者,所以肯定會存在分析不正確的地方,如有發現歡迎指正,謝謝! 規定$ROCKET
linux驅動由淺入深系列:usb子系統之四(android平臺滑鼠驅動程式碼分析)
android上的usb口是支援OTG(on the go)的,USB OTG既可以作為Host又可以作為Device,我們本文來看一下android手機作為Host連線滑鼠的情況。OTG是如何做到既可以做Host又可以作為Device的呢 標準usb接頭中有四根線:vbu
使用Orange進行資料探勘之聚類分析(2)------K-means
一、基本k均值演算法 1 根據使用者指定的引數K,首先選擇K個初始化質心; 2 然後每個點指派到最近的質心,指派到一個質心的點形成一個簇。 3 更新每個簇的質心 4重複步驟2、3,直到簇不在發生變化。 虛擬碼描述如下: 選擇K個點作為初始質心 repeat 將每個質
linux驅動由淺入深系列:顯示子系統之二(基於android的分析)
上一篇文章中介紹了應用層對顯示系統的使用,我們操作framebuffer在螢幕上畫出了圖形。這次我們一起來看一下android中顯示子系統各個模組的功能。android系統音訊系統在高通平臺上的框圖:HWUIUI硬體加速,從Androd 3.0(Honeycomb)開始,An
我的android多執行緒程式設計之路(2)之RxJava Schedulers原始碼分析
寫在伊始 上一篇介紹了執行緒的一些基礎知識和工作這麼久以後對於多執行緒部分的使用經驗之路,這篇主要對RxJava執行緒控制部分進行分析。 RxJava(本文就RxJava2.0分析) 說實話,近一年多一直在用rxjava進行專案架構的編寫及封裝及一些非
[原理分析]Linux下的棧溢位案例分析-GDB除錯操練[2]
摘要: 原版本中的問題主要在於除錯過程中,蠻力的痕跡太重,沒有很好地體現常用的除錯準則;本文在原版本的基礎上,融入參考文獻中提及的除錯原則,重新審視和操練該問題,希望儘量體現出除錯中常用的思維法則。 測試的平臺:1. ubuntu 9; gcc 4.4.1; G
linux之Segment Fault錯誤分析[2]
簡而言之,產生段錯誤就是訪問了錯誤的記憶體段,一般是你沒有許可權,或者根本就不存在對應的實體記憶體,尤其常見的是訪問0地址. 一 般來說,段錯誤就是指訪問的記憶體超出了系統所給這個程式的記憶體空間,通常這個值是由gdtr來儲存的,他是一個48位的暫存器,其中的32位是儲存由
七.linux開發之uboot移植(七)——uboot原始碼分析2-啟動第二階段之start_armboot函式分析1
一.uboot啟動第二階段之start_armboot函式簡介 1.start_armboot函式簡介 (1)這個函式在uboot/lib_arm/board.c的第444行開始到908行結束。 (2)、即一個函式組成uboot第二階段 2、
Android輸入子系統之應用程式註冊訊息監聽過程分析
應用程式註冊訊息監聽過程分析 CPP層InputManagerService啟動後就需要監聽按鍵輸入了,當InputManagerService監聽到鍵盤輸入的事件後就需要分發鍵盤事件,但是分發給誰呢?這裡首先應該是分發給當前啟用的Window視窗,但是當前啟
dlmalloc 2.8.6 原始碼詳解—[6]除錯分析
分析堆溢位漏洞不能僅僅停留在瞭解dlmalloc堆分配器執行原理,還需要通過偵錯程式觀察其執行過程並在堆記憶體中識別堆的資料結構,這就像實習醫生學習做手術一樣,最終檢驗還是要在手術檯上。 1 除錯程式碼 #include<stdio.h>
java反序列化-ysoserial-除錯分析總結篇(2)
前言: 這篇主要分析commonCollections2,呼叫鏈如下圖所示: 呼叫鏈分析: 分析環境:jdk1.8.0 反序列化的入口點為src.zip!/java/util/PriorityQueue.java 此時將會對佇列呼叫siftdown函式,其中佇列中包含了兩個元素,
Redis 數據結構之dict(2)
value ash 每次 earch 定義 索引 user popu adding 本文及後續文章,Redis版本均是v3.2.8 上篇文章《Redis 數據結構之dict》,我們對dict的結構有了大致的印象。此篇文章對dict是如何維護數據結構的做個詳細的理解
HTML之課堂小記2
clas 連接符 class earch 命名法 劃線 例如 for lock BEM命名法: 這裏的B,指的是block,也就是“search-form” 這裏的E,指的是element,也就是跟隨在search-form後的“username”,“password”和“