天天看點

Dynamic function tracing events

本文翻譯自LWN文章“Dynamic function tracing events”,原文 連結

從核心引入tracepoint開始,開發者們就對這些tracepoint是否為核心ABI的一部分而發生過争執。過去由于破壞了已有存在依賴的使用者态程式,tracepoint相關變更被回退過。同時,對内部代碼無法改變的恐慌使得在多個核心子系統中新增tracepoint變得困難。如今,一個新的tracing功能被提了出來以避開這些問題。

tracepoint是否作為核心ABI的一部分并非是無關緊要的問題。核心ABI承諾運作應用程式不會因核心更新而遭到破壞。很明确這個承諾在過去就已擴充覆寫到tracepoint。尤其是2011年當一個tracepoint變更因破壞了powertop而不得不被回退。一些核心維護者禁止或嚴格控制其維護的子系統中新增tracepoint,就是擔心類似的事情會同樣發生在自己身上。其結果導緻核心缺乏使用者認為有用的tracepoint。

這個主題在多個會議上作為議程讨論過,包括2017年維護者峰會。正是那時提出一個更聰明的想法:與其将tracepoint放置到敏感位置,不如由開發者簡單地做好标記,而這些标記可以在運作時顯示地連接配接并轉化成tracepoint。通過跳出束縛 (jump through some hoops) 以此期望保證這個新機制将不會建立任何新的ABI。接下來幾個月一切歸于平靜。

但最近tracing的維護者Steve Rostedt面臨該提案的一個變化,他稱之為“動态建立基于函數的事件 (dynamically created function-based events) ”。細節上發生了一些變化,但ABI規避本質上保持一緻。關鍵細節差異來源于其觀察到核心已經在特定位置上有了tracing代碼可以利用的一種類型的标記。核心代碼通常帶有正常用于代碼分析的參數編譯。結果,每個函數都以調用mcount() (或新編譯器使用的__fentry()__ ) 開始。當分析使用者态程式時,mcount()追蹤每個函數的調用并是以很耗時。盡管核心使用支援諸如function tracing的特性版本來替換mcount()。但大多時候都是直接整體打上mcount()調用,隻是可以在運作時需要tracing特定函數調用時啟用。

也存在其他可能使用函數入口鈎子的場景。Rostedt的更新檔可在運作時任何核心函數的開始處啟用建立tracepoint。在tracefs控制檔案系統挂載的前提下,一個新tracepoint可通過如下指令建立:

echo 'SyS_openat(int dfd, string path, x32 flags, x16 mode)' \
    > /sys/kernel/tracing/function_events           

SyS_openat()是openat()系統調用的核心實作,該指令請求在SyS_openat()入口處建立一個tracepoint。4個值将從tracepoint報告出來:目錄檔案描述符 (dfd),給定路徑名(path),以及标記和模式參數。這個tracepoint将在events/functions下顯示出來,跟核心中其他tracepoint看上去一樣。也可以像平常那樣被查詢,啟用和關閉。有趣地是,這個例子中的路徑指向使用者空間,但tracing系統能恰當地擷取并列印出相應資料。

很明顯還存在進一步的工作要做:“我需要重寫function graph tracer,并且能在函數傳回時增加動态事件”。其核心部分看上去已經有了且能正常工作。但這裡遺留了一個重要問題:這是否已經足夠確定避免建立一個新ABI的核心接口集?Mathieu Desnoyers擔心仍然不夠。

讓這些工具在函數名/參數上挂個鈎子無法解決該問題。一旦核心代碼變更,廣泛使用的trace分析工具将開始變得不正常。而此時,其内部函數簽名将會成為ABI。

Linus Torvalds卻不同意該擔心。核心鈎子需要的額外步驟隐含了不同狀态視角:

每個人*了解*這像一個調試工具:如果你有一個gdb腳本顯示某些資訊,接着你到處修改源代碼,*明顯*你同樣需要回過頭來修改調試腳本。你并沒有沒有保持源代碼不變來使gdb腳本無需變更,這看上去很傻。

相反,顯示的tracepoint使人們相信它們有着長遠的意義。

如果現實與該觀點一緻,那麼新的動态tracepoint機制将在緩解ABI問題有很大幫助。大量核心新增的tracepoint将很可能被丢棄,因為開發者将簡單地使用動态變種來替代。将來增加tracepoint時,相對可能的是這些tracepoint将被設計成支援某些系統管理工具,并且在外部看上去是ABI的一部分。

當然那是假定這個系列更新檔最終會被合入。Alexei Starovoitov對此有些不同意見,他抱怨新接口在kprobe現有的基礎上增加很少。同時他也不喜歡面向文本的接口,建議使用BPF來替代以提取核心資料的某些特定資訊。但Rostedt指出,許多開發者因BPF上手複雜性而退卻,而更偏向簡單的。

Rostedt認為該接口将很有用,但如果其他人存在不同意見的話他将不再繼續開發:“如果其他人認為這将有用,那麼我想讓他們現在大聲地說出來”。然而迄今為止,幾乎沒有人明确表達出來。如果動态函數tracing機制的确是其他開發者想要的,他們需要顯示發聲以表示支援。

繼續閱讀