您現在的位置是:首頁 > 遊戲
問題排查利器:Linux 原生跟蹤工具 Ftrace 必知必會
指令大全在哪裡下
本文地址:
https://www。ebpf。top/post/ftrace_tools
TLDR,建議收藏,需要時查閱。
如果你只是需要快速使用工具來進行問題排查,包括但不限於函式呼叫棧跟蹤、函式呼叫子函式流程、函式返回結果,那麼推薦你直接使用
BCC trace
或
Brendan Gregg
封裝的
perf-tools
工具即可,本文嘗試從手工操作 Ftrace 跟蹤工具的方式展示在底層是如何透過 tracefs 實現這些能力的。如果你對某個跟蹤主題感興趣,建議直接跳轉到相關的主題檢視。
快速說明:
kprobe 為核心中提供的動態跟蹤機制,
/proc/kallsym
中的函式幾乎都可以用於跟蹤,但是核心函式可能隨著版本演進而發生變化,為非穩定的跟蹤機制,數量比較多。
uprobe 為使用者空間提供的動態機制;
tracepoint 是核心提供的靜態跟蹤點,為穩定的跟蹤點,需要研發人員程式碼編寫,數量有限;
usdt 為使用者空間提供的靜態跟蹤點 【本次暫不涉及】
Ftrace 是 Linux 官方提供的跟蹤工具,在 Linux 2。6。27 版本中引入。Ftrace 可在不引入任何前端工具的情況下使用,讓其可以適合在任何系統環境中使用。
Ftrace 可用來快速排查以下相關問題:
特定核心函式呼叫的頻次 (function)
核心函式在被呼叫的過程中流程(呼叫棧) (function + stack)
核心函式呼叫的子函式流程(子呼叫棧)(function graph)
由於搶佔導致的高延時路徑等
Ftrace 跟蹤工具由效能分析器(profiler)和跟蹤器(tracer)兩部分組成:
效能分析器
,用來提供統計和直方圖資料(需要 CONFIG_ FUNCTION_PROFILER=y)
函式效能分析
直方圖
跟蹤器
,提供跟蹤事件的詳情:
函式跟蹤(function)
跟蹤點(tracepoint)
kprobe
uprobe
函式呼叫關係(function_graph)
hwlat 等
除了操作原始的檔案介面外,也有一些基於 Ftrace 的前端工具,比如 perf-tools 和 trace-cmd (介面 KernelShark)等。整體跟蹤及前端工具架構圖如下:
圖片來自於 《Systems Performance Enterprise and the Cloud 2nd Edition》 14。1 P706
Ftrace 的使用的介面為 tracefs 檔案系統,需要保證該檔案系統進行載入:
tracing 目錄下核心檔案介紹如下表格,當前可僅關注黑體加粗的項,其他項可在需要的時候再進行回顧:
perf_tools 包含了一個復位所有 ftrace 選型的工具指令碼,在跟蹤不符合預期的情況下,建議先使用
reset-ftrace
進行復位,然後再進行測試。
1。 核心函式呼叫跟蹤
基於 Ftrace 的核心函式呼叫跟蹤整體架構如下所示:
圖片來自於 《Systems Performance Enterprise and the Cloud 2nd Edition》 14。4 P713
這裡我們嘗試對於核心中的系統呼叫函式
__arm64_sys_openat
進行跟蹤(前面兩個下劃線),需要注意的是
__arm64_sys_openat
是在 arm64 結構體系下
sys_openat
系統呼叫的包裝,如果在 x86_64 架構下則為
__x64_sys_openat()
,由於我們本地的電腦是 M1 晶片,所以演示的樣例以 arm64 為主。
在不同的體系結構下,可以在
/proc/kallsym
檔案中搜索確認。
後續的目錄,如無特殊說明,都預設位於
/sys/kernel/debug/tracing/
根目錄。
我們可以看到上述的結果表明了函式呼叫的任務名稱、PID、CPU、標記位、時間戳及函式名字。
在
perf_tools
工具集中的前端封裝工具為
functrace
,需要注意的是該工具預設不會設定 tracing_on 為 1, 需要在啟動前進行設定,即 ”echo 1 > tracing_on“。
perf_tools
工具集中
kprobe
也可以實現類似的效果,底層基於 kprobe 機制實現,ftrace 機制中的 kprobe 在後續章節會詳細介紹。
2。 函式被呼叫流程(棧)
在第 1 部分我們獲得了核心函式的呼叫,但是有些場景我們更可能希望獲取呼叫該核心函式的流程(即該函式是在何處被呼叫),這需要透過設定
options/func_stack_trace
選項實現。
透過上述跟蹤記錄,我們可以發現記錄同時展示了函式呼叫的記錄和被呼叫的函式流程,
__arm64_sys_openat
的被呼叫棧如下:
=> __arm64_sys_openat=> invoke_syscall=> el0_svc_common。constprop。0=> do_el0_svc=> el0_svc=> el0_sync_handler=> el0_sync
perf_tools
工具集中
kprobe
透過新增 ”-s“ 引數實現同樣的功能,執行的命令如下:
$ 。/kprobe -s ‘p:__arm64_sys_openat’
3。 函式呼叫子流程跟蹤(棧)
如果想要分析核心函式呼叫的子流程(即本函式呼叫了哪些子函式,處理的流程如何),這時需要用到
function_graph
跟蹤器,從字面意思就可看出這是函式呼叫關係跟蹤。
基於
__arm64_sys_openat
子流程呼叫關係的跟蹤的完整設定過程如下:
在本樣例中
__arm64_sys_openat
函式的呼叫子流程僅包括
do_sys_openat2()
子函式,而
do_sys_openat2()
函式又呼叫了
getname()/get_unused_fd_flags()
等子函式。
這種完整的子函式呼叫關係,對於我們學習核心原始碼和分析線上的問題都提供了便利,排查問題時則可以順藤摸瓜逐步縮小需要分析的範圍。
在
perf_tools
工具集的前端工具為
funcgraph
,使用 funcgraph 啟動命令如下所示:
$。/funcgraph -m 3 __arm64_sys_openat
如果函式呼叫棧比較多,直接檢視跟蹤記錄則非常不方便,基於此社群補丁
[PATCH] ftrace: Add vim script to enable folding for function_graph traces
提供了一個基於 vim 的配置,可透過樹狀關係來摺疊和展開函式呼叫的最終記錄,vim 設定完整如下:
將上述指令儲存為 function-graph-fold。vim 檔案,在 vim 使用時透過 -S 引數指定上述配置,就可實現按照層級展示跟蹤記錄。在 vim 中,可透過 za 展開,zc 摺疊跟蹤記錄。(透過檔案分析,我們需要在
cat trace
檔案時候重定向到檔案)。
$ vim -S function-graph-fold。vim trace。log
4。 核心跟蹤點(tracepoint)跟蹤
可基於 ftrace 跟蹤核心靜態跟蹤點,可跟蹤的完整列表可透過 available_events 檢視。events 目錄下檢視到各分類的子目錄,詳見下圖:
這裡直接使用 tracepoint 跟蹤
sys_openat
系統呼叫,設定如下:
我們透過設定
sys_enter_openat/enable
開啟對於
sys_enter_openat
的跟蹤,trace 檔案中的跟蹤記錄格式與
sys_enter_openat/format
中的 print 章節的格式一致。
print fmt: “dfd: 0x%08lx, filename: 0x%08lx, flags: 0x%08lx, mode: 0x%08lx” 。。。
Filter 跟蹤記錄條件過濾
關於
sys_enter_openat/filter
檔案為跟蹤記錄的過濾條件設定,格式如下:
field operator value
其中:
field 為
sys_enter_openat/format
中的欄位。
operator 為比較符
整數支援:==,!=,、,<=,>= 和 & ,
字串支援 ==,!=,~ 等,其中 ~ 支援 shell 指令碼中萬用字元 *,?,[] 等操作。
不同的條件也支援 && 和 || 進行組合。
如需要透過 format 格式中的 mode 欄位過濾:
field:umode_t mode; offset:40; size:8; signed:0;
只需要將進行如下設定即可:
$ sudo echo ‘mode != 0’ > events/syscalls/sys_enter_openat/filter
如果需要清除 filter,直接設定為 0 即可:
$ sudo echo 0 > events/syscalls/sys_enter_openat/filter
5。 kprobe 跟蹤
kprobe 為核心提供的動態跟蹤機制。與第 1 節介紹的函式跟蹤類似,但是 kprobe 機制允許我們跟蹤函式任意位置,還可用於獲取函式引數與結果返回值。使用 kprobe 機制跟蹤函式須是
available_filter_functions
列表中的子集。
kprobe 設定檔案和相關檔案如下所示,其中部分檔案為設定 kprobe 跟蹤函式後,Ftrace 自動建立:
kprobe_events
設定 kprobe 跟蹤的事件屬性;
完整的設定格式如下,其中 GRP 使用者可以直接定義,如果不設定預設為
kprobes
:
p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] # 設定 probe 探測點r[:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] # 函式地址的返回跟蹤-:[GRP/]EVENT # 刪除跟蹤
kprobes/
設定後動態生成,用於控制是否啟用該核心函式的跟蹤;
kprobes/
設定後動態生成,kprobe 函式跟蹤過濾器,與上述的跟蹤點 fliter 類似;
kprobes/
設定後動態生成,kprobe 事件顯示格式;
kprobe_profile
kprobe 事件統計效能資料;
Kprobe 跟蹤過程可以指定函式引數的顯示格式,這裡我們先給出
sys_openat
函式原型:
SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode);
**跟蹤函式入口引數 **
這裡仍然以
__arm64_sys_openat
函式為例,演示使用 kpboe 機制進行跟蹤:
**跟蹤函式返回值 **
kprobe 可用於跟蹤函式返回值,格式如下:
r[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS]
例如:
$ sudo echo ‘r:my_grp/arm64_sys_openat __arm64_sys_openat ret=$retval’ >> kprobe_events
變數
$retval
引數表示函式返回值,其他的使用格式與 kprobe 類似。
6。 uprobe 跟蹤
uprobe 為使用者空間的動態跟蹤機制,格式和使用方式與 kprobe 的方式類似,但是由於是使用者態程式跟蹤需要指定跟蹤的二進位制檔案和偏移量。
p[:[GRP/]EVENT]] PATH:OFFSET [FETCHARGS] # 跟蹤函式入口r[:[GRP/]EVENT]] PATH:OFFSET [FETCHARGS] # 跟蹤函式返回值-:[GRP/]EVENT] # 刪除跟蹤點
這裡以跟蹤
/bin/bash
二進位制檔案中的
readline()
函式為例:
uprobe 跟蹤是跟蹤使用者態的函式,因此需要指定二進位制檔案+符號偏移量才能進行跟蹤。不同系統中的二進位制版本或者編譯方式不同,會導致函式符號表的位置不同,因此需要跟蹤前進行確認。
7。 總結
至此,我們完整介紹 Ftrace 的整體應用場景,也透過具體的設定,學習了使用的完整流程。
實際問題排查中,考慮到效率和易用性,推薦大家這樣選擇:
如果排查問題機器上支援 eBPF技術,首選
BCC trace
及相關工具;
否則推薦使用
perf-tools
;
最後的招數就是使用本文 Ftrace 的完整流程了。
但目前基於 eBPF 的工具還未支援
function_graph
跟蹤器,特定場景下還需要 ftrace 的
function_graph
跟蹤器的配合。
Ftrace 與 eBPF 並非是相互替代,而是相互補充協同關係,在後續的問題排查案例中我們將看到這一點。
參考
高效分析 Linux 核心原始碼
, 相關程式碼參見
這裡
。
Linux kprobe 除錯技術使用
ftrace 在實際問題中的應用
《Systems Performance Enterprise and the Cloud 2nd Edition》
推薦文章
- 因釣魚成癮被妻子起訴離婚,開庭日又因釣魚遲到,凡事皆要有度
等到媳婦下班後問孩子,今天爸爸帶你到哪玩了,孩子的回答永遠都是,爸爸帶我買魚食了,爸爸帶我去修魚杆了,要麼就是爸爸帶我到水庫了等等,從來都是和釣魚有關的事情...
- 「湖南名刊大刊」擷英大文史 激揚主旋律——記湖南省政協機關刊《文史博覽》
2017年5月,《文史博覽》圍繞“我省歷史建築保護與利用”主題,組織高校青年學子開展長達4個月的“尋找身邊古建築”活動,團隊深入永州、懷化、郴州、邵陽等地,外圍透過網易直播參與的人數超過200萬...
- 女朋友說放假來我家,我該準備點什麼?買個自噴漆寫個“拆”就行
一位細心的哥們,在看了他發的照片之後,終於發現了問題出在哪裡······15. 好漂亮的火鳥16.“打針的時候針尖明明是中空的,為什麼扎進去不會帶出來一撮肉...