日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

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

發(fā)布時間:2025/3/15 windows 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Binder子系统之调试分析(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一. 概述

在博客以前有寫過關(guān)于binder系列,大概寫了10篇關(guān)于binder的文章,從binder驅(qū)動,到native層,再到framework,一路寫到app層的使用。有興趣的可以看看?Binder系列—開篇。

二.Binder驅(qū)動調(diào)試

看過Binder系列文章的同學,會發(fā)現(xiàn)Binder IPC過程最終都交給Binder Driver來完成,這是真正干跨進程通信活的地方,那么意味著這里會有各種核心的通信log,比如binder open, mmap, ioctl等操作都可以通過某種方式來打開相應(yīng)調(diào)試信息來分析。對于binder driver存在16類調(diào)試log開關(guān),如下:

2.1 debug_mask

Log類型 mask值 解釋
BINDER_DEBUG_USER_ERROR 1 用戶使用錯誤
BINDER_DEBUG_FAILED_TRANSACTION 2 transaction失敗
BINDER_DEBUG_DEAD_TRANSACTION 4 transaction死亡
BINDER_DEBUG_OPEN_CLOSE 8 binder的open/close/mmap信息
BINDER_DEBUG_DEAD_BINDER 16 binder/node死亡信息
BINDER_DEBUG_DEATH_NOTIFICATION 32 binder死亡通知信息
BINDER_DEBUG_READ_WRITE 64 binder的read/write信息
BINDER_DEBUG_USER_REFS 128 binder引用計數(shù)
BINDER_DEBUG_THREADS 256 binder_thread信息
BINDER_DEBUG_TRANSACTION 512 transaction信息
BINDER_DEBUG_TRANSACTION_COMPLETE 1024 transaction完成信息
BINDER_DEBUG_FREE_BUFFER 2048 可用buffer信息
BINDER_DEBUG_INTERNAL_REFS 4096 binder內(nèi)部引用計數(shù)
BINDER_DEBUG_BUFFER_ALLOC 8192 同步內(nèi)存分配信息
BINDER_DEBUG_PRIORITY_CAP 16384 調(diào)整binder線程的nice值
BINDER_DEBUG_BUFFER_ALLOC_ASYNC 32768 異步內(nèi)存分配信息

每一項mask值通過將1左移N位,也就是等于2的倍數(shù)

2.2 調(diào)試開關(guān)

通過節(jié)點/sys/module/binder/parameters/debug_mask來動態(tài)控制選擇開啟上表中的debug log.

(1)例如打開BINDER_DEBUG_OPEN_CLOSE調(diào)試開關(guān),則通過adb shell執(zhí)行如下命令:

echo 8 > /sys/module/binder/parameters/debug_mask

(2)再例如同時打開BINDER_DEBUG_FAILED_TRANSACTION和BINDER_DEBUG_DEAD_BINDER,將各個mask值相加即可,16+2 =18.

echo 18 > /sys/module/binder/parameters/debug_mask

(3)要打開多個開關(guān),只需將各個開關(guān)的mask值相加寫入debug_mask即可。打開調(diào)試開關(guān)后,可通過adb shell,執(zhí)行cat /proc/kmsg | grep binder,即可查看相應(yīng)的binder log信息。

2.3 原理

mask相加,其實現(xiàn)其實是利用或運算,通過一個變量控制16個開關(guān),而不是采用16個變量,這是比較經(jīng)典的設(shè)計方案。在binder Driver中通過下面語句完成節(jié)點控制debug的功能:

module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);

module_param_named的功能:

  • 首先會生成/sys/module/binder/parameters/目錄;
  • module_param_named的第一個參數(shù)為debug_mask,則會在parameters目錄下創(chuàng)建debug_mask文件節(jié)點;
  • 當通過echo NUM > debug_mask命令,會觸發(fā)動態(tài)修改module_param_named的第二個參數(shù)binder_debug_mask值,這是個靜態(tài)uint32_t類型數(shù)據(jù);
  • 驅(qū)動中輸出debug log都是通過調(diào)用binder_debug()方法,該方法通過與binder_debug_mask變量做或運算來判斷相應(yīng)類型的log信息是否需要輸出。

binder_debug宏定義,如下:

#define binder_debug(mask, x...) \do { \if (binder_debug_mask & mask) \pr_info(x); \} while (0)

當然,也可以通過代碼直接修改binder_debug_mask值來控制調(diào)試開關(guān),默認值為:

binder_debug_mask = BINDER_DEBUG_USER_ERROR |BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;

另外,在/sys/module/binder/parameters/目錄還有另外兩個節(jié)點,分別為proc_no_lock, stop_on_user_error,其實現(xiàn)原理也基本差不多。

  • proc_no_lock節(jié)點:與之對應(yīng)binder驅(qū)動的binder_debug_no_lock變量,這是bool類型變量,該開關(guān)含義為在輸出某些統(tǒng)計調(diào)試方法中是否加鎖;默認為N;
  • stop_on_user_error節(jié)點:與之對應(yīng)binder驅(qū)動的binder_stop_on_user_error變量,這是int類型變量,另外,修改該節(jié)點還會觸發(fā)調(diào)用binder_set_stop_on_user_error()方法;該開關(guān)含義是指當觸發(fā)BINDER_DEBUG_USER_ERROR類型錯誤時是否讓整個binder系統(tǒng)進入休眠等待狀態(tài),默認值為0,代表不會即便發(fā)生該類型錯誤系統(tǒng)不會被掛住,而是繼續(xù)執(zhí)行。

三 實戰(zhàn)

3.1 BINDER_DEBUG_OPEN_CLOSE

當打開調(diào)試開關(guān)BINDER_DEBUG_OPEN_CLOSE時,主要輸出binder的open, mmap, close, flush, release方法中的log信息

具體kernel log,如下:

  • binder_open:?4681:4681
  • binder_mmap:?4681 b6b42000-b6c40000 (1016 K) vma 200071 pagep 79f
  • binder:?4681 close vm area b6b42000-b6c40000 (1016 K) vma 2220051 pagep 79f
  • binder_flush:?4681 woke 0 threads
  • binder_release:?4681 threads 1, nodes 0 (ref 0), refs 2, active transactions 0, buffers 1, pages 1
  • 3.2 解析

    上面各行l(wèi)og所對應(yīng)的信息項:

  • binder_open:?group_leader->pid:pid
  • binder_mmap:?pid?vm_start-vm_end (vm_size?K) vma vm_flags pagep?vm_page_prot
  • binder:?pid?close vm area vm_start-vm_end (vm_size?K) vma vm_flags pagepvm_page_prot
  • binder_flush:?pid?woke?wake_count?threads
  • binder_release:?pid?threads?threads, nodes?nodes?(ref?incoming_refs), refsoutgoing_refs, active transactions?active_transactions, buffers?buffers, pagespage_count
  • 進一步說明其中部分關(guān)鍵詞的含義:

    • vm_page_prot:是指當前進程的VMA訪問權(quán)限;
    • wake_count:是指該進程喚醒了處于BINDER_LOOPER_STATE_WAITING休眠等待狀態(tài)的線程個數(shù);
    • threads是指該進程中的線程個數(shù);
    • nodes代表該進程中創(chuàng)建binder_node個數(shù);
    • incoming_refs指向當前node的refs個數(shù);
    • outgoing_refs指向其他進程的refs個數(shù);
    • active_transactions是指當前進程中所有binder線程的transactions總和;
    • buffers是指當前進程已分配的buffer個數(shù);
    • page_count是指當前進程已分配的物理page個數(shù)。

    3.3 對應(yīng)函數(shù)

    上述log每一行相對應(yīng)的函數(shù):

  • binder_open()
  • binder_vma_open() 或者 binder_mmap()
  • binder_vma_close()
  • binder_deferred_flush() 由binder_flush調(diào)用(見下方調(diào)用棧)
  • binder_deferred_release() 由binder_release調(diào)用(見下方調(diào)用棧)
  • binder_flush調(diào)用棧:

    binder_flush binder_defer_work(proc, BINDER_DEFERRED_FLUSH);queue_work(binder_deferred_workqueue, &binder_deferred_work);binder_deferred_func //通過 DECLARE_WORK(binder_deferred_work, binder_deferred_func);binder_deferred_flush

    binder_release調(diào)用棧:

    binder_release binder_defer_work(proc, BINDER_DEFERRED_RELEASE);queue_work(binder_deferred_workqueue, &binder_deferred_work);binder_deferred_func //通過 DECLARE_WORK(binder_deferred_work, binder_deferred_func);binder_deferred_release

    當binder所在進程結(jié)束時會調(diào)用binder_release。 binder_open打開binder驅(qū)動/dev/binder,這是字符設(shè)備,獲取文件描述符。在進程結(jié)束的時候會有一個關(guān)閉文件系統(tǒng)的過程中會調(diào)用驅(qū)動close方法,該方法相對應(yīng)的是release()方法。

    但并不是每個close系統(tǒng)調(diào)用都會觸發(fā)調(diào)用release()方法. 只有真正釋放設(shè)備數(shù)據(jù)結(jié)構(gòu)才調(diào)用release(),內(nèi)核維持一個文件結(jié)構(gòu)被使用多少次的計數(shù),即便是應(yīng)用程序沒有明顯地關(guān)閉它打開的文件也適用: 內(nèi)核在進程exit()時會釋放所有內(nèi)存和關(guān)閉相應(yīng)的文件資源, 通過使用close系統(tǒng)調(diào)用最終也會release binder.

    四. 其他實例

    4.1 BINDER_DEBUG_DEAD_BINDER

    //debug_id, node的引用次數(shù),死亡通知個數(shù)?
    binder: node?1078337?now dead, refs?1, death?0

    //ref->proc->pid, ref->debug_id, ref->desc(handle)?
    binder:?13839?delete ref?1078335?desc?1?has death notification

    //proc->pid, thread->pid, (u64)cookie, death?
    binder:?1788:1805?BC_DEAD_BINDER_DONE?9ce308c0?found?f10a5400

    4.2 BINDER_DEBUG_FREE_BUFFER

    查詢可用buffer:

    //proc->pid, thread->pid, (u64)data_ptr, buffer->debug_id, buffer->transaction?
    binder:?463:5919?BC_FREE_BUFFER ub4641028?found buffer?1183795?for?finishedtransaction?
    binder:?277:2771?BC_FREE_BUFFER ub6c58028?found buffer?1183806?for?activetransaction

    另外,buffer->transaction ? “active” : “finished”

    位于方法binder_thread_write()

    4.3 BINDER_DEBUG_BUFFER_ALLOC_ASYNC(異步)

    申請和釋放異步buffer:

    //proc->pid, size, proc->free_async_space
    binder:?1788: binder_alloc_buf size?148?async free?520004
    binder:?1788: binder_free_buf size?148?async free?520192

    解析:

    • binder_alloc_buf:進程1788,申請148 Bytes,則該進程的可用異步空間大小520004 Bytes;
    • binder_free_buf: 進程1788,釋放148 Bytes,則該進程的可用異步空間大小520192 Bytes;

    內(nèi)存大小計算:

    free_async_space = 520004 Bytes,再釋放148 Bytes后,則可用大小應(yīng)該是 520152 Bytes,這里卻為520192 Bytes,這里多出來的40 Bytes是哪來得呢?這是因為binder_free_buf還會同時釋放struct binder_buffer,該結(jié)構(gòu)體大小則為40 Bytes.

    另外:buffer申請內(nèi)存binder_alloc_buf和釋放內(nèi)存binder_free_buf,除了本身內(nèi)存申請和釋放,會同時伴隨著binder_buffer結(jié)構(gòu)體的創(chuàng)建和釋放,這便是每次操作40 Bytes差距所在。另外, 對于64位系統(tǒng),binder_buffer大小為80 Bytes.

    初始化值

    proc->free_async_space = proc->buffer_size / 2 = (1M-8K)/2 = 520192 Bytes。當進程剛打開binder驅(qū)動,執(zhí)行完binder_mmap方法后,異步可用空間總大小為 520192 Bytes.

    4.4 BINDER_DEBUG_BUFFER_ALLOC(同步)

    // 參數(shù):proc->pid, size, buffer, buffer_size?
    binder:?1788: binder_alloc_buf size?76?got buffer?c7800128?size?208?
    binder:?1788:?allocate?pages?c7801000-c7800000?
    // 參數(shù):proc->pid, new_buffer_size, new_buffer?
    binder:?1788: add free buffer, size?92, at?c780019c?
    binder:?1788:?free?pages?c7801000-c7800000?
    //參數(shù):proc->pid, buffer, prev?
    binder:?1788: merge free, buffer?c780019c?share page with?c7800128

    解析:

    • binder_alloc_buf: 從proc->free_buffers這棵紅黑色樹,找到一塊大小大于并最接近76Bytes的buffer,該buffer大小為208Bytes;
    • binder_update_page_range:申請一個page大小的物理內(nèi)存,地址為c7801000-c7800000。
    • binder_insert_free_buffer: 將空閑buffer添加到proc->free_buffers;
    • binder_update_page_range:釋放一個page大小的物理內(nèi)存,地址為c7801000-c7800000。
    • binder_delete_free_buffer:在執(zhí)行binder_free_buf()過程,合并釋放的buffer,由于該buffer跟上一個buffer共享同一page,則無需釋放。

    五. 小結(jié)

    本文主要介紹控制調(diào)試開關(guān)和各個開關(guān)的含義及原理,最后再通過一個實例來進一步來說明其中一項開關(guān)打開后的log信息該如何分析。后續(xù)會介紹更多的調(diào)試含義和調(diào)試工具,以及從上至下binder是如何通信。

    原文地址:http://gityuan.com/2016/08/27/binder-debug/

    總結(jié)

    以上是生活随笔為你收集整理的Binder子系统之调试分析(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产精品伊人久久 | 91福利在线导航 | 一级黄色片片 | 一区二区三区成人 | 人妻互换 综合 | 91精品人妻一区二区三区四区 | 日韩欧美黄色片 | www.久久久久久久久 | 98久久久| 欧美日一区二区 | 69视频在线看| 女同二区 | 红桃视频黄色 | 久久国产中文字幕 | 91免费官网| 欧美人与禽zozzo性之恋的特点 | 久免费一级suv好看的国产 | 国产传媒精品 | 波多野结衣在线视频播放 | 男人桶进美女尿囗 | 亚洲国产精品久久人人爱 | 免费黄色在线看 | 国产成人aaaa | 成人午夜免费观看 | 原神淫辱系列同人h | 日韩aⅴ视频 | 中文字幕第27页 | 三年在线观看视频 | 亚洲日本一区二区 | 一本—道久久a久久精品蜜桃 | 免费黄色一级视频 | 久久久噜噜噜www成人网 | 婷婷激情成人 | 99xav | 韩国三级hd中文字幕叫床浴室 | 少妇h视频 | 日韩av综合在线 | 亚洲最大成人在线视频 | 亚洲7777 | 初高中福利视频网站 | 操穴影院| 香蕉久久夜色精品国产使用方法 | 久久精品视频91 | 久久久久久久久免费看无码 | 91一区二区 | 国产又粗又硬又长又爽的演员 | 少妇一级淫片免费观看 | 国产av天堂无码一区二区三区 | 精品乱子伦一区二区 | 少妇真实被内射视频三四区 | 一区二区三区日韩欧美 | 日韩欧美国产三级 | 免费在线看黄色 | 黑人一区 | 申鹤乳液狂飙 | 国产精品黑丝 | 日韩精品视频一区二区在线观看 | 老熟妇仑乱视频一区二区 | 天天操天 | 五月婷婷网站 | 影音先锋成人网 | 精品在线一区 | 色一区二区三区 | 伦理亚洲| 成人午夜电影网站 | 国产高清一区在线观看 | 野外做受又硬又粗又大视频√ | 91久久精品国产91久久 | 国产伦精品一区二区三区视频免费 | 欧美黄色一级视频 | 第四色在线视频 | 在线看一区| 四虎影院在线观看免费 | 亚洲三级电影 | 午夜少妇久久久久久久久 | 青青草综合在线 | 亚洲美女在线视频 | 中文综合网 | 91精品国产一区 | 国产老熟妇精品观看 | 在线免费观看av网站 | 亚欧洲精品在线视频免费观看 | 欧美性一区二区三区 | 成人一区三区 | 四虎成人在线 | 国产精品高潮呻吟视频 | 中文字幕有码在线观看 | 无码国精品一区二区免费蜜桃 | 老师张开让我了一夜av | 老头老太做爰xxx视频 | 人人澡人人澡人人澡 | 成人www.| 亚洲一区二区三区色 | 中文字幕乱码视频 | 欧美成人区 | 伊人久久一区二区三区 | 人妻体内射精一区二区三区 | 电影寂寞少女免费观看 | 女大学生的家政保姆初体验 |