最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

一文教你使用trace查看函數(shù)調(diào)用關(guān)系|分析Linux性能

2022-12-05 20:55 作者:補給站Linux內(nèi)核  | 我要投稿
  • 抓取函數(shù)調(diào)用流程關(guān)系

  • 抓取函數(shù)耗時

  • 抓取代碼片耗時

  • 抓取函數(shù)里每個子函數(shù)時間戳

  • 抓取事件信息

trace是內(nèi)核自帶的工具,相比于perf工具,trace只管抓trace數(shù)據(jù)并沒有分析,perf在trace數(shù)據(jù)分析方面做出了很多成果。 但是我們現(xiàn)在就想看一下底層多調(diào)用關(guān)系,所以使用trace抓一下數(shù)據(jù)是非常有必要的,還可以分析一下驅(qū)動性能。

因為trace工具是內(nèi)核自帶的,所以我們配置一下內(nèi)核就可以使用了:

圖片

trace 通過 debugfs 向用戶態(tài)提供了訪問接口,所以還需要將 debugfs 編譯進內(nèi)核。激活對 debugfs 的支持,在 make menuconfig 時到 Kernel hacking 菜單下選中對 debugfs 文件系統(tǒng)的支持:

圖片

系統(tǒng)啟動后,進入文件系統(tǒng),執(zhí)行:

掛載debugfs后即可使用trace。

tracing 目錄下文件和目錄比較多,有些是各種跟蹤器共享使用的,有些是特定于某個跟蹤器使用的。在操作這些數(shù)據(jù)文件時,使用 echo 命令來修改其值,也可以在程序中通過文件讀寫相關(guān)的函數(shù)來操作這些文件的值。

  • README文件提供了一個簡短的使用說明,展示了 ftrace 的操作命令序列??梢酝ㄟ^ cat 命令查看該文件以了解概要的操作流程。

  • current_tracer用于設(shè)置或顯示當前使用的跟蹤器;使用 echo 將跟蹤器名字寫入該文件可以切換到不同的跟蹤器。系統(tǒng)啟動后,其缺省值為 nop ,即不做任何跟蹤操作。在執(zhí)行完一段跟蹤任務(wù)后,可以通過向該文件寫入 nop 來重置跟蹤器。

  • available_tracers記錄了當前編譯進內(nèi)核的跟蹤器的列表,可以通過 cat 查看其內(nèi)容;寫 current_tracer 文件時用到的跟蹤器名字必須在該文件列出的跟蹤器名字列表中。

  • trace文件提供了查看獲取到的跟蹤信息的接口??梢酝ㄟ^ cat 等命令查看該文件以查看跟蹤到的內(nèi)核活動記錄,也可以將其內(nèi)容保存為記錄文件以備后續(xù)查看。

  • set_graph_function設(shè)置要清晰顯示調(diào)用關(guān)系的函數(shù),顯示的信息結(jié)構(gòu)類似于 C 語言代碼,這樣在分析內(nèi)核運作流程時會更加直觀一些。在使用 function_graph 跟蹤器時使用;缺省為對所有函數(shù)都生成調(diào)用關(guān)系序列,可以通過寫該文件來指定需要特別關(guān)注的函數(shù)。

  • buffer_size_kb用于設(shè)置單個 CPU 所使用的跟蹤緩存的大小。跟蹤器會將跟蹤到的信息寫入緩存,每個 CPU 的跟蹤緩存是一樣大的。跟蹤緩存實現(xiàn)為環(huán)形緩沖區(qū)的形式,如果跟蹤到的信息太多,則舊的信息會被新的跟蹤信息覆蓋掉。注意,要更改該文件的值需要先將 current_tracer 設(shè)置為 nop 才可以。

  • tracing_on用于控制跟蹤的暫停。有時候在觀察到某些事件時想暫時關(guān)閉跟蹤,可以將 0 寫入該文件以停止跟蹤,這樣跟蹤緩沖區(qū)中比較新的部分是與所關(guān)注的事件相關(guān)的;寫入 1 可以繼續(xù)跟蹤。

  • available_filter_functions記錄了當前可以跟蹤的內(nèi)核函數(shù)。對于不在該文件中列出的函數(shù),無法跟蹤其活動。

  • set_ftrace_filter和 set_ftrace_notrace在編譯內(nèi)核時配置了動態(tài) ftrace (選中CONFIG_DYNAMIC_FTRACE 選項)后使用。前者用于顯示指定要跟蹤的函數(shù),后者則作用相反,用于指定不跟蹤的函數(shù)。如果一個函數(shù)名同時出現(xiàn)在這兩個文件中,則這個函數(shù)的執(zhí)行狀況不會被跟蹤。這些文件還支持簡單形式的含有通配符的表達式,這樣可以用一個表達式一次指定多個目標函數(shù);注意,要寫入這兩個文件的函數(shù)名必須可以在文件 available_filter_functions 中看到。缺省為可以跟蹤所有內(nèi)核函數(shù),文件 set_ftrace_notrace 的值則為空。

  • available_events 當前編譯進內(nèi)核的可以監(jiān)控的事件。

  • set_event 跟蹤的事件類型,名字必須在available_events列出的跟蹤器名字列表中。

trace 當前包含多個跟蹤器,用于跟蹤不同類型的信息,比如進程調(diào)度、中斷關(guān)閉等。可以查看文件 available_tracers 獲取內(nèi)核當前支持的跟蹤器列表。在編譯內(nèi)核時,也可以看到內(nèi)核支持的跟蹤器對應的選項。

  • nop跟蹤器不會跟蹤任何內(nèi)核活動,將 nop 寫入 current_tracer 文件可以刪除之前所使用的跟蹤器,并清空之前收集到的跟蹤信息,即刷新 trace 文件。

  • function跟蹤器可以跟蹤內(nèi)核函數(shù)的執(zhí)行情況;可以通過文件 set_ftrace_filter 顯示指定要跟蹤的函數(shù)。function_graph跟蹤器可以顯示類似 C 源碼的函數(shù)調(diào)用關(guān)系圖,這樣查看起來比較直觀一些;可以通過文件

  • set_grapch_function 顯示指定要生成調(diào)用流程圖的函數(shù)。 sched_switch跟蹤器可以對內(nèi)核中的進程調(diào)度活動進行跟蹤。

  • irqsoff跟蹤器和preemptoff跟蹤器分別跟蹤關(guān)閉中斷的代碼和禁止進程搶占的代碼,并記錄關(guān)閉的最大時長,preemptirqsoff跟蹤器則可以看做它們的組合。

那具體怎么用呢?


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)?


比如我們抓一次spi輸出傳輸,驅(qū)動用的是kernel自帶的spidev驅(qū)動:

spidev_ioctrl 被echo到set_grapch_function 屬性里面,就可以查看整個spidev_ioctrl 函數(shù)的調(diào)用流程,但是實際上我們執(zhí)行的時候會發(fā)現(xiàn)一個事情,抓取來的數(shù)據(jù)太多了,許多無關(guān)的、我們不太關(guān)心的函數(shù)調(diào)用關(guān)系也被抓進去了,導致抓出來的數(shù)據(jù)非常亂!

所以最好是利用set_ftrace_filter進行一些過濾。

所以針對這種情況,我們應該這樣設(shè)置:

在spi傳輸里,我們主要關(guān)系spi的函數(shù)和dma的函數(shù),所以大概抓一下這些字眼即可,還可以按需自己添加過濾語句。

ps:因為spin_lock語句也帶了spi字眼,也會被誤抓進來,所以最后也把他剔除掉。

最后得出的數(shù)據(jù)就正常多了:

以上僅列舉部分信息,有興趣的小伙伴可以自行嘗試。

抓取函數(shù)耗時

有時候,也許我們也要通過程序的耗時來分析程序的性能,可以這么做:

同樣也是以spidev驅(qū)動為例:

這樣可以非常直觀的看到spidev_ioctrl 執(zhí)行的耗時。

其中, 帶左側(cè)時間顯示一塊:

延遲比較大的部分,會有+、#等特殊標號:

圖片

抓取代碼片耗時

有時,我們需要抓取一大片多個函數(shù)耗時??梢赃@么做:

以i2c傳輸為例,抓取twi_set_start到sunxi_i2c_handler函數(shù)的時間:

這樣我們即可抓取Linux里面執(zhí)行i2cget的時候去讀取0x50地址器件時i2c傳輸 twi_set_start 函數(shù)到 sunxi_i2c_handler 函數(shù)的耗時,即兩個時間戳相減:

可以看得出耗時為24us。

當然,我們也可以使用do_gettimeofday函數(shù)來統(tǒng)計耗時,不過比較麻煩,需要在檢測的地方手動添加:

timeval 結(jié)構(gòu)體定義:

甚至也可以用ktime_to_us來實現(xiàn):

方法是多種多樣的。

抓取函數(shù)里每個子函數(shù)時間戳

在第一點里面,抓取函數(shù)調(diào)用流程里面只能看到每個子函數(shù)的耗時,不能看到時間戳,那么如何能看到每個子函數(shù)的時間戳呢?和第一點的手段類似:

區(qū)別操作就是添加了:echo funcgraph-tail > trace_options

主要是在函數(shù)結(jié)束顯示函數(shù)名。這樣方便使用grep找出函數(shù)的執(zhí)行時間,默認disable:

hide: echo nofuncgraph-tail > trace_options

show: echo funcgraph-tail > trace_options

最后結(jié)果非常直觀:

graph_ent代表函數(shù)開始執(zhí)行,graph_ret代表函數(shù)結(jié)束。

抓取事件信息

有時候我們需要根據(jù)事件來抓取信息,就可以使用set_event了??梢?cat available_events 查看獲得支持的跟蹤event列表,這個支持的比較多,配置相對簡單,只需向set_event寫相應值即可。

比如我們要查看spi的事件,可以先看下available_event 里有無spi事件:

可以看出,我們這里支持七個spi事件,其對應的頭文件在:Linux-4.9/include/trace/events/spi.h文件。感興趣的可以查看里面的內(nèi)容實現(xiàn)。這里我們把所有的spi事件都打印出來:


即可看到我們需要跟蹤的spi事件:


原文作者:人人極客社區(qū)



一文教你使用trace查看函數(shù)調(diào)用關(guān)系|分析Linux性能的評論 (共 條)

分享到微博請遵守國家法律
雷山县| 昭觉县| 府谷县| 丘北县| 溧水县| 梁山县| 无锡市| 名山县| 彭山县| 思茅市| 株洲县| 若尔盖县| 昂仁县| 莱阳市| 茌平县| 天镇县| 墨江| 涿鹿县| 宜君县| 正镶白旗| 陇南市| 任丘市| 怀来县| 花垣县| 拉萨市| 阿勒泰市| 平陆县| 信宜市| 苏州市| 安庆市| 游戏| 玛曲县| 大名县| 旅游| 兴安县| 奈曼旗| 都昌县| 叶城县| 日喀则市| 巴林左旗| 昔阳县|