官术网_书友最值得收藏!

1.1.1 Linux的跟蹤與診斷技術簡介

在eBPF出現之前,Linux已經提供了多種跟蹤與診斷基礎功能模塊,包括kprobe/kretprobe、uprobe/uretprobe、fentry/fexit以及tracepoint。這些功能模塊為跟蹤和診斷提供了豐富的支持。目前,大部分eBPF的跟蹤與診斷功能都是基于這些功能模塊實現的。接下來,我們將分別介紹這些功能的工作原理,以便更好地理解eBPF的工作原理。

1)kprobe/kretprobe:kprobe用于在函數的入口處插入代碼進行跟蹤和調試;kretprobe是kprobe的擴展,用于在函數的返回處插入代碼進行跟蹤和調試。

kprobe/kretprobe的工作原理如圖1-1所示。首先,被探測的函數入口指令會被替換成int 3指令。當被跟蹤的函數執行時,將引發int 3異常中斷,然后int 3異常處理程序將被觸發,進而調用相應的kprobe處理函數。kprobe的處理函數有兩種:一種是執行用戶所注冊的kprobe函數;另一種是執行通過kretprobe機制注冊的kprobe函數。值得注意的是,通過kretprobe注冊的kprobe處理函數會更改函數的返回地址,將該地址替換為kprobe處理函數的地址。因此,當程序執行ret指令并返回時,將直接跳轉至kretprobe的處理函數處,并執行用戶所注冊的kretprobe函數。

圖1-1 kprobe/kretprobe工作原理

2)uprobe/uretprobe:與kprobe/kretprobe的運作機制基本相似,但uprobe/uretprobe跟蹤的是用戶態函數。uretprobe作為uprobe的補充功能,當部署uretprobe函數時,會同時部署uprobe處理函數,以便將函數的返回地址更改為uretprobe處理函數的地址。這樣,當函數執行完畢并準備返回時,將直接跳轉至uretprobe處理函數并繼續執行相應的操作。

3)fentry/fexit:相較于kprobe/kretprobe通過int 3指令來觸發執行kprobe處理程序,fentry/fexit的實現方式略有不同。在內核編譯時,它會通過GCC(GNU Compiler Collection,一個開源的編譯器系統)的編譯選項-mfentry在每個函數的入口處加入NOP指令[1]。當用戶插入具體的fentry/fexit處理函數時,這些NOP指令會被替換成調用相應的處理函數指令。盡管ftrace早期就使用了fentry/fexit功能,但直到Linux內核5.5版本,用戶才能直接使用該功能。值得一提的是,fexit的實現原理與kretprobe和uretprobe相同,也是在fentry處理函數內將函數的返回地址更改成fexit處理函數的地址。

4)tracepoint:tracepoint是在內核中定義的一系列預定義的事件跟蹤點。這些跟蹤點位于內核代碼中的關鍵位置,允許開發人員插入自定義的跟蹤代碼,以捕獲特定事件的信息。我們可以在/sys/kernel/debug/tracing/events/目錄看到內核支持的跟蹤點。它與fentry/fexit具有一樣高的性能。

盡管kprobe/kretprobe、uprobe/uretprobe、fentry/fexit和tracepoint都具有跟蹤診斷功能,但各自具有獨特的意義。kprobe和uprobe雖然性能相對較差,但具有高度的靈活性,可以在內核中的任意位置進行跟蹤。相比之下,fentry/fexit和tracepoint性能最佳,但靈活性稍差,只能跟蹤特定的內核位置。我們還從靈活性、性能和支持eBPF的內核版本等關鍵指標進行了總結和比較,如表1-1所示。

表1-1 關鍵指標對比

主站蜘蛛池模板: 丹巴县| 越西县| 太保市| 集安市| 邹城市| 南城县| 武鸣县| 万盛区| 宁化县| 和硕县| 南江县| 武义县| 尚义县| 阳西县| 怀仁县| 临安市| 隆昌县| 临漳县| 清新县| 安龙县| 七台河市| 团风县| 青川县| 静宁县| 广饶县| 贵港市| 湖北省| 措勤县| 张掖市| 横山县| 瑞金市| 诸暨市| 绍兴县| 辽宁省| 辰溪县| 南江县| 大庆市| 宁武县| 司法| 威宁| 万源市|