Binder駆動のdebug情報とデータ構造
13364 ワード
Binder debugや問題の解析を行う場合は、通常、現在のBinderステータス情報を見る必要があります.KernelはSYSシステムを通じて、/sys/kernel/debug/binder/、それぞれ: State:現在のBinderのすべてのプロセスのステータス. Stats:Binder転送の統計. Transactions:現在のBinderのすべてのプロセスの転送ステータス. transaction_log:最近のBinder転送. failed_transaction_log:最近失敗したBinder転送.
これらのDebug情報を理解するには、Binderドライバに関連するデータ構造定義が必要です.これらの情報はほとんど駆動中のすべての構造体に関連しており,以下,両者を組み合わせて情報の具体的な内容を見る.まず、Binderドライバの最も基本的なデータ構造binder_を見てみましょう.proc.Binder_procはBinderプロセスを記述するためのデータ構造であり、1つのプロセスには1つのbinder_しかない.Procは、他の構造体がこのデータ構造に関連付けられます.つまりbinder_Procは、Binderスレッド、Binderリファレンス、Binderメモリなど、すべてのBinderプロセスに関する情報を検索できます.
State
Stateが最初に記録したときに死亡したBinder(dead node).これらのBinderのプロセスはすでに死んでおり、現在はどのプロセスにも属していないため、グローバルなキューに記録されている(binder_dead_nodes).死亡記録は以下のように示されている.
Dead nodesに関するデータ構造はbinder_node,binder_Nodeはbinderエンティティを表します.プロセス内のbinder_NodeはProcのnodesレッドブラックツリーによって管理され、死亡したbinder_Nodeはグローバルhlist binder_によってdead_Nodes管理、もう一つのグローバルbinder_context_mgr_nodeはsystem_を記録するために使用されますserverのbinder_node.定義は次のとおりです.
Dead nodes情報の後には、現在のシステム内のすべてのBinderプロセスの情報が続きます.この情報には、プロセス内のBinderスレッドの状態、Binderエンティティ情報、Binderリファレンス情報、binder buffer情報が含まれます.
スレッドステータスBinderプロセス内のすべてのBinderスレッドのPIDとスレッドステータス、binder_threadデータ構造とスレッド状態は以下のように定義される.
次に、BinderプロセスにおけるBinderエンティティの情報を説明し、Dead nodesを参照します.次に印刷されるのは、プロセス中にBinderが参照する情報であり、関連データ構造はbinder_である.refは、Binderエンティティのエージェントとして使用されます.
最後にBinderプロセスにおけるBinder bufferの情報.関連データ構造はbinder_Binder転送データを格納するbuffer.
Stats
Statsには,転送命令の統計,内部オブジェクトの統計などを含むBinderの統計が含まれる.最初に出力されるのはすべてのBinderの統計で、その後Binderプロセスごとに統計を出力します.出力例は次のとおりです.
Binder統計binder_を介してstatsで表すと、
BC_で先頭のコマンドは、アプリケーション層がBinderドライバに送信するリクエストコマンドであり、以下のように定義されている.
Cmd
Description
Args
Code
BC_TRANSACTION
Clientがサーバに要求データを送信
binder_transaction_data: the sent command
10763886080x40286300
BC_REPLY
ServerがClientに返信(応答)データを送信
binder_transaction_data: the sent command
10763886090x40286301
BC_ACQUIRE_RESULT
まだ実現していない
---
10740293140x40046302
BC_FREE_BUFFER
マッピングされたメモリを解放します.
void *: ptr to transaction data received on a read
10740293150x40046303
BC_INCREFS
Binderの弱い参照数を増やす
int: descriptor
10740293160x40046304
BC_ACQUIRE
Binderの強い参照数を増やす
int: descriptor
10740293170x40046305
BC_RELEASE
Binderの強い参照数を減らす
int: descriptor
10740293180x40046306
BC_DECREFS
Binderの弱い参照数を減らす
int: descriptor
10740293190x40046307
BC_INCREFS_DONE
BindeエンティティのプロセスがBC_を処理しました.INCREFSのフィードバック
void : ptr to bindervoid : cookie
10742914640x40086308
BC_ACQUIRE_DONE
BindeエンティティのプロセスがBC_を処理しました.ACQUIREのフィードバック
void : ptr to bindervoid : cookie
10742914650x40086309
BC_ATTEMPT_ACQUIRE
まだ実現していない
---
10742914660x4008630a
BC_REGISTER_LOOPER
通知ドライバスレッドプールのスレッドが作成されました
---
253550x630b
BC_ENTER_LOOPER
スレッドがプライマリサイクルに入ったことを通知し、データを受信できます.
---
253560x630c
BC_EXIT_LOOPER
通知は、スレッドがプライマリサイクルを終了し、データを受信しないように駆動します.
---
253570x630d
BC_REQUEST_DEATH_NOTIFICATION
Binderが参照するプロセスでは、Binderのエンティティの死亡通知を取得する必要があります.
void : ptr to bindervoid : cookie
10742914700x4008630e
BC_CLEAR_DEATH_NOTIFICATION
Binderを取得したエンティティの死亡通知をクリア
void : ptr to bindervoid : cookie
10742914710x4008630f
BC_DEAD_BINDER_DONE
エンティティの死亡通知書を受信したプロセスは、参照を削除した後、本コマンドでドライバに通知します.
void *: cookie
10740293280x40046310
BR_で先頭のコマンドは、Binderドライバがアプリケーション層に送信する返信コマンドであり、以下のように定義されている.
Cmd
Description
Args
Code
BR_ERROR
メモリの割り当てに失敗したなど、内部エラーが発生しました.
int: error code
21477749760x80047200
BR_OK
操作完了
---
291850x7201
BR_TRANSACTION
送信元のBC_に対応TRANSACTION
binder_transaction_data: the received command
21501342740x80287202
BR_REPLY
送信元のBC_に対応REPLY
binder_transaction_data: the received command
21501342750x80287203
BR_ACQUIRE_RESULT
まだ実現していない
---
21477749800x80047204
BR_DEAD_REPLY
インタラクション中に相手のプロセスまたはスレッドが死亡していることが判明した場合、メッセージを返します.
---
291890x7205
BR_TRANSACTION_COMPLETE
受信者は、このメッセージをBC_として送信するTRANSACTIONまたはBC_REPLY送信成功のフィードバック
---
291900x7206
BR_INCREFS
Binderローカルオブジェクトの弱い参照数を増やす
void : ptr to bindervoid : cookie for binder
21480371270x80287207
BR_ACQUIRE
Binderローカルオブジェクトの強い参照数を増やす
void : ptr to bindervoid : cookie for binder
21480371280x80287208
BR_RELEASE
Binderローカルオブジェクトの強い参照数を減らす
void : ptr to bindervoid : cookie for binder
21480371290x80287209
BR_DECREFS
Binderローカルオブジェクトの弱い参照数を減らす
void : ptr to bindervoid : cookie for binder
21480371300x8028720a
BR_ACQUIRE_RESULT
まだ実現していない
---
21482992750x800c720b
BR_NOOP
仕事をしないで、
---
291960x720c
BR_SPAWN_LOOPER
ドライバは、受信者のすべてのスレッドがビジー状態であることを発見し、受信データに備えてより多くのスレッドを作成する必要があることを受信者に送信します.
---
291970x720d
BR_FINISHED
まだ実現していない
---
291980x720e
BR_DEAD_BINDER
Binderエンティティの死亡通知をBinderリファレンスを取得するプロセスに送信
void **cookie
21477749910x8004720f
BR_CLEAR_DEATH_NOTIFICATION_DONE
死亡通知クリア完了
void **cookie
21477749920x80047210
BR_FAILED_REPLY
不正な参照番号が送信された場合、メッセージが返されます.
---
292010x7211
transaction_logとfailed_transaction_log
この2つのファイルノードは、最近32回の成功と失敗の伝送記録を提供し、出力情報はほぼ同じである.
関連するデータ構造はbinder_transaction_log_entry.この構造体はBinder伝送の記述として用いられ,Binder伝送が開始されるたびにdebugのためにグローバル構造体に記録される.
Transactions
Transactionsには、現在のシステム内のすべてのBinderプロセスの転送状態が記録されています.出力例は次のとおりです.
この出力情報には多くのデータ構造の内容が含まれており、buffer情報とbinder_buffer関連、thread情報とbinder_thread関連、もう一つの最も重要な伝送イベントはbinder_transactionで説明します.
これらのDebug情報を理解するには、Binderドライバに関連するデータ構造定義が必要です.これらの情報はほとんど駆動中のすべての構造体に関連しており,以下,両者を組み合わせて情報の具体的な内容を見る.まず、Binderドライバの最も基本的なデータ構造binder_を見てみましょう.proc.Binder_procはBinderプロセスを記述するためのデータ構造であり、1つのプロセスには1つのbinder_しかない.Procは、他の構造体がこのデータ構造に関連付けられます.つまりbinder_Procは、Binderスレッド、Binderリファレンス、Binderメモリなど、すべてのBinderプロセスに関する情報を検索できます.
struct binder_proc {
struct hlist_node proc_node; /* hlist , binder_procs */
struct rb_root threads; /* Binder */
struct rb_root nodes; /* Binder */
struct rb_root refs_by_desc; /* Binder , handle key */
struct rb_root refs_by_node; /* Binder , node key */
int pid; /* PID */
struct vm_area_struct *vma; /* */
struct mm_struct *vma_vm_mm; /* */
struct task_struct *tsk; /* task */
struct files_struct *files; /* file */
struct hlist_node deferred_work_node; /* hlist , binder_deferred_list , binder */
int deferred_work; /* Binder defer flag, PUT_FILES,FLUSH,RELEASE */
void *buffer; /* Binder */
ptrdiff_t user_buffer_offset; /* Binder */
struct list_head buffers; /* Binder buffer */
struct rb_root free_buffers; /* Binder buffer */
struct rb_root allocated_buffers; /* Binder buffer */
size_t free_async_space; /* */
struct page **pages; /* */
size_t buffer_size; /* Binder */
uint32_t buffer_free; /* Binder */
struct list_head todo; /* Binder todo */
wait_queue_head_t wait; /* Binder */
struct binder_stats stats; /* Binder */
struct list_head delivered_death; /* Binder */
int max_threads; /* Binder */
int requested_threads; /* */
int requested_threads_started; /* */
int ready_threads; /* */
long default_priority; /* */
struct dentry *debugfs_entry; /* debugfs */
};
State
Stateが最初に記録したときに死亡したBinder(dead node).これらのBinderのプロセスはすでに死んでおり、現在はどのプロセスにも属していないため、グローバルなキューに記録されている(binder_dead_nodes).死亡記録は以下のように示されている.
Dead nodesに関するデータ構造はbinder_node,binder_Nodeはbinderエンティティを表します.プロセス内のbinder_NodeはProcのnodesレッドブラックツリーによって管理され、死亡したbinder_Nodeはグローバルhlist binder_によってdead_Nodes管理、もう一つのグローバルbinder_context_mgr_nodeはsystem_を記録するために使用されますserverのbinder_node.定義は次のとおりです.
struct binder_node {
int debug_id; /* binder node id, */
struct binder_work work; /* binder 。 / binder, binder */
union {
struct rb_node rb_node; /* Proc nodes rb_node */
struct hlist_node dead_node; /* binder_node, , binder 。 binder, binder node , dead node */
};
struct binder_proc *proc; /* binder node */
struct hlist_head refs; /* binder node , binder node */
int internal_strong_refs; /* binder node */
int local_weak_refs; /* binder */
int local_strong_refs; /* binder */
void __user *ptr; /* binder , */
void __user *cookie; /* */
unsigned has_strong_ref:1; /* */
unsigned pending_strong_ref:1; /* */
unsigned has_weak_ref:1; /* */
unsigned pending_weak_ref:1; /* */
unsigned has_async_transaction:1; /* Todo */
unsigned accept_fds:1; /* binder*/
unsigned min_priority:8; /* Binder */
struct list_head async_todo; /* */
}
Dead nodes情報の後には、現在のシステム内のすべてのBinderプロセスの情報が続きます.この情報には、プロセス内のBinderスレッドの状態、Binderエンティティ情報、Binderリファレンス情報、binder buffer情報が含まれます.
スレッドステータスBinderプロセス内のすべてのBinderスレッドのPIDとスレッドステータス、binder_threadデータ構造とスレッド状態は以下のように定義される.
enum {
BINDER_LOOPER_STATE_REGISTERED = 0x01, /* (BC_REGISTER_LOOPER) */
BINDER_LOOPER_STATE_ENTERED = 0x02, /* (BC_ENTER_LOOPER) */
BINDER_LOOPER_STATE_EXITED = 0x04, /* */
BINDER_LOOPER_STATE_INVALID = 0x08, /* */
BINDER_LOOPER_STATE_WAITING = 0x10, /* */
BINDER_LOOPER_STATE_NEED_RETURN = 0x20 /* */
};
struct binder_thread {
struct binder_proc *proc; /* */
struct rb_node rb_node; /* , binder_proc->threads */
int pid; /* PID */
int looper; /* looper , */
struct binder_transaction *transaction_stack; /* Binder */
struct list_head todo; /* Binder todo */
uint32_t return_error; /* */
uint32_t return_error2; /* 2 */
wait_queue_head_t wait; /* Binder */
struct binder_stats stats; /* Binder */
};
次に、BinderプロセスにおけるBinderエンティティの情報を説明し、Dead nodesを参照します.次に印刷されるのは、プロセス中にBinderが参照する情報であり、関連データ構造はbinder_である.refは、Binderエンティティのエージェントとして使用されます.
struct binder_ref {
/* Lookups needed: */
/* node + proc => ref (transaction) */
/* desc + proc => ref (transaction, inc/dec ref) */
/* node => refs + procs (proc exit) */
int debug_id; /* id, */
struct rb_node rb_node_desc; /* , binder_proc->refs_by_desc */
struct rb_node rb_node_node; /* , binder_proc->refs_by_node */
struct hlist_node node_entry; /* hlist , binder_node->refs */
struct binder_proc *proc; /* Binder */
struct binder_node *node; /* Binder */
uint32_t desc; /* handle */
int strong; /* */
int weak; /* */
struct binder_ref_death *death; /* */
};
最後にBinderプロセスにおけるBinder bufferの情報.関連データ構造はbinder_Binder転送データを格納するbuffer.
struct binder_buffer {
struct list_head entry; /* list , binder_proc->buffers */
struct rb_node rb_node; /* , binder_proc->free_buffers(buffer ) binder_proc->allocated_buffers(buffer ) */
unsigned free:1; /* */
unsigned allow_user_free:1; /* */
unsigned async_transaction:1; /* */
unsigned debug_id:29; /* id, */
struct binder_transaction *transaction; /* Binder */
struct binder_node *target_node; /* Binder */
size_t data_size; /* */
size_t offsets_size; /* */
uint8_t data[0]; /* */
}
Stats
Statsには,転送命令の統計,内部オブジェクトの統計などを含むBinderの統計が含まれる.最初に出力されるのはすべてのBinderの統計で、その後Binderプロセスごとに統計を出力します.出力例は次のとおりです.
Binder統計binder_を介してstatsで表すと、
struct binder_stats {
int br[_IOC_NR(BR_FAILED_REPLY) + 1]; /* Binder (Binder Driver Return Protocol)*/
int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1]; /* Binder (Binder Driver Command Protocol)*/
int obj_created[BINDER_STAT_COUNT]; /* Binder , 1 */
int obj_deleted[BINDER_STAT_COUNT]; /* Binder , 1 */
};
BC_で先頭のコマンドは、アプリケーション層がBinderドライバに送信するリクエストコマンドであり、以下のように定義されている.
Cmd
Description
Args
Code
BC_TRANSACTION
Clientがサーバに要求データを送信
binder_transaction_data: the sent command
10763886080x40286300
BC_REPLY
ServerがClientに返信(応答)データを送信
binder_transaction_data: the sent command
10763886090x40286301
BC_ACQUIRE_RESULT
まだ実現していない
---
10740293140x40046302
BC_FREE_BUFFER
マッピングされたメモリを解放します.
void *: ptr to transaction data received on a read
10740293150x40046303
BC_INCREFS
Binderの弱い参照数を増やす
int: descriptor
10740293160x40046304
BC_ACQUIRE
Binderの強い参照数を増やす
int: descriptor
10740293170x40046305
BC_RELEASE
Binderの強い参照数を減らす
int: descriptor
10740293180x40046306
BC_DECREFS
Binderの弱い参照数を減らす
int: descriptor
10740293190x40046307
BC_INCREFS_DONE
BindeエンティティのプロセスがBC_を処理しました.INCREFSのフィードバック
void : ptr to bindervoid : cookie
10742914640x40086308
BC_ACQUIRE_DONE
BindeエンティティのプロセスがBC_を処理しました.ACQUIREのフィードバック
void : ptr to bindervoid : cookie
10742914650x40086309
BC_ATTEMPT_ACQUIRE
まだ実現していない
---
10742914660x4008630a
BC_REGISTER_LOOPER
通知ドライバスレッドプールのスレッドが作成されました
---
253550x630b
BC_ENTER_LOOPER
スレッドがプライマリサイクルに入ったことを通知し、データを受信できます.
---
253560x630c
BC_EXIT_LOOPER
通知は、スレッドがプライマリサイクルを終了し、データを受信しないように駆動します.
---
253570x630d
BC_REQUEST_DEATH_NOTIFICATION
Binderが参照するプロセスでは、Binderのエンティティの死亡通知を取得する必要があります.
void : ptr to bindervoid : cookie
10742914700x4008630e
BC_CLEAR_DEATH_NOTIFICATION
Binderを取得したエンティティの死亡通知をクリア
void : ptr to bindervoid : cookie
10742914710x4008630f
BC_DEAD_BINDER_DONE
エンティティの死亡通知書を受信したプロセスは、参照を削除した後、本コマンドでドライバに通知します.
void *: cookie
10740293280x40046310
BR_で先頭のコマンドは、Binderドライバがアプリケーション層に送信する返信コマンドであり、以下のように定義されている.
Cmd
Description
Args
Code
BR_ERROR
メモリの割り当てに失敗したなど、内部エラーが発生しました.
int: error code
21477749760x80047200
BR_OK
操作完了
---
291850x7201
BR_TRANSACTION
送信元のBC_に対応TRANSACTION
binder_transaction_data: the received command
21501342740x80287202
BR_REPLY
送信元のBC_に対応REPLY
binder_transaction_data: the received command
21501342750x80287203
BR_ACQUIRE_RESULT
まだ実現していない
---
21477749800x80047204
BR_DEAD_REPLY
インタラクション中に相手のプロセスまたはスレッドが死亡していることが判明した場合、メッセージを返します.
---
291890x7205
BR_TRANSACTION_COMPLETE
受信者は、このメッセージをBC_として送信するTRANSACTIONまたはBC_REPLY送信成功のフィードバック
---
291900x7206
BR_INCREFS
Binderローカルオブジェクトの弱い参照数を増やす
void : ptr to bindervoid : cookie for binder
21480371270x80287207
BR_ACQUIRE
Binderローカルオブジェクトの強い参照数を増やす
void : ptr to bindervoid : cookie for binder
21480371280x80287208
BR_RELEASE
Binderローカルオブジェクトの強い参照数を減らす
void : ptr to bindervoid : cookie for binder
21480371290x80287209
BR_DECREFS
Binderローカルオブジェクトの弱い参照数を減らす
void : ptr to bindervoid : cookie for binder
21480371300x8028720a
BR_ACQUIRE_RESULT
まだ実現していない
---
21482992750x800c720b
BR_NOOP
仕事をしないで、
---
291960x720c
BR_SPAWN_LOOPER
ドライバは、受信者のすべてのスレッドがビジー状態であることを発見し、受信データに備えてより多くのスレッドを作成する必要があることを受信者に送信します.
---
291970x720d
BR_FINISHED
まだ実現していない
---
291980x720e
BR_DEAD_BINDER
Binderエンティティの死亡通知をBinderリファレンスを取得するプロセスに送信
void **cookie
21477749910x8004720f
BR_CLEAR_DEATH_NOTIFICATION_DONE
死亡通知クリア完了
void **cookie
21477749920x80047210
BR_FAILED_REPLY
不正な参照番号が送信された場合、メッセージが返されます.
---
292010x7211
transaction_logとfailed_transaction_log
この2つのファイルノードは、最近32回の成功と失敗の伝送記録を提供し、出力情報はほぼ同じである.
関連するデータ構造はbinder_transaction_log_entry.この構造体はBinder伝送の記述として用いられ,Binder伝送が開始されるたびにdebugのためにグローバル構造体に記録される.
struct binder_transaction_log_entry {
int debug_id; /* transaction log ID */
int call_type; /* ,0:call, 1:async, 2:replay */
int from_proc; /* PID*/
int from_thread; /* PID */
int target_handle; /* Binder , -1 */
int to_proc; /* PID*/
int to_thread; /* PID, 0 */
int to_node; /* Binder node ID */
int data_size; /* */
int offsets_size; /* */
};
struct binder_transaction_log {
int next; /* log */
int full; /* log */
struct binder_transaction_log_entry entry[32]; /* log */
};
static struct binder_transaction_log binder_transaction_log;
static struct binder_transaction_log binder_transaction_log_failed;
Transactions
Transactionsには、現在のシステム内のすべてのBinderプロセスの転送状態が記録されています.出力例は次のとおりです.
この出力情報には多くのデータ構造の内容が含まれており、buffer情報とbinder_buffer関連、thread情報とbinder_thread関連、もう一つの最も重要な伝送イベントはbinder_transactionで説明します.
struct binder_work {
struct list_head entry; /* */
enum {
BINDER_WORK_TRANSACTION = 1,
BINDER_WORK_TRANSACTION_COMPLETE,
BINDER_WORK_NODE,
BINDER_WORK_DEAD_BINDER,
BINDER_WORK_DEAD_BINDER_AND_CLEAR,
BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
} type;
};
......
struct binder_transaction {
int debug_id; /* ID, */
struct binder_work work; /* */
struct binder_thread *from; /* */
struct binder_transaction *from_parent; /* */
struct binder_proc *to_proc; /* */
struct binder_thread *to_thread; /* */
struct binder_transaction *to_parent; /* */
unsigned need_reply:1; /* */
/* unsigned is_dead:1; */ /* not used at the moment */
struct binder_buffer *buffer; /* buffer */
unsigned int code; /* */
unsigned int flags; /* , TF_ONE_WAY */
long priority; /* */
long saved_priority; /* */
kuid_t sender_euid; /* uid */
}