可觀測性與追蹤

ftrace(核心函式追蹤器)

/ EFF-trayss /

假設你想從內部觀察核心——想看你的程式做某件事時,哪些核心函式被呼叫、以什麼順序。ftrace 就是直接內建在 Linux 核心本身、專為此而生的追蹤器。你什麼都不用裝;這個能力早已編進核心,你透過讀寫特殊檔案來驅動它。它最突出的功能是函式追蹤器:它能在核心函式被進入時就記錄下來。

它實際上是這樣運作的。ftrace 透過一個虛擬檔案系統來控制,傳統上掛載在 /sys/kernel/tracing(這就是 tracefs)。你藉由把純文字寫進它的控制檔、再把結果讀回來,來設定並執行一次追蹤——例如把「function」寫進 current_tracer 這個檔案,就開啟函式追蹤器,而讀取 trace 這個檔案就拿到擷取到的輸出。樸素的函式追蹤器會在每個核心函式被進入時記下它,這是一股消防水柱。更易讀的函式圖追蹤器(function-graph)則把呼叫顯示成一棵巢狀、縮排的呼叫樹,每個呼叫旁邊印著它的耗時,於是你能「看見」執行的形狀、以及核心內部時間花在哪裡——很像文字版的火焰圖。你可以過濾到特定函式以免被淹沒,也可以只追蹤單一行程。在底層,函式追蹤器倚賴編譯器插入的鉤子(核心建置時帶有 mcount/fentry 樁),由 ftrace 在執行期把它們補進補出。

它之所以重要,是因為它是隨時可用、零相依的核心追蹤方式——在基本上任何現代 Linux 機器上,你都能用幾個 echo 指令、不裝任何額外軟體就開始追蹤,這在一個鎖死的正式環境裡無比寶貴。誠實的提醒:全函式追蹤負擔很高、產出量極大,所以你幾乎一定要過濾;它追蹤的是核心,不是你使用者空間的應用程式邏輯;而且雖然原始檔案介面到處都能用,它很瑣碎難用,這正是更高階前端(trace-cmd、以及 perf 的 ftrace 模式)存在、以更舒服地驅動它的原因。

$ cd /sys/kernel/tracing $ echo function_graph > current_tracer $ echo 1 > tracing_on ; sleep 1 ; echo 0 > tracing_on $ cat trace # 2.114 us | vfs_read() { # 1.882 us | ext4_file_read_iter(); # | }

完全透過 tracefs 檔案驅動的函式圖追蹤器,顯示出一棵帶有每呼叫耗時的巢狀呼叫樹,呈現核心內部的執行。

ftrace 不是單一工具而是一套框架:kprobes、uprobes、tracepoints 全都透過同一個 tracefs 介面呈現,所以「ftrace」常指整套核心追蹤機制,函式追蹤器只是其中最有名的一部分。

又称
function tracerfunction-graph tracertracefs核心函式追蹤函式圖追蹤器