您好,登錄后才能下訂單哦!
今天小編給大家分享一下Linux下怎么使用Bpftrace的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
Bpftrace是Linux的新開源跟蹤程序,用于分析生產性能問題和故障排除軟件。 它的用戶和貢獻者包括Netflix,Facebook,Red Hat,Shopify等,它是由Alastair Robertson創(chuàng)建的, Alastair Robertson是一位才華橫溢的英國開發(fā)商,贏得了各種編碼競賽。
在終端 使用 sudo 執(zhí)行下面的命令安裝 bpftrace:
$ sudo dnf install bpftrace
使用“hello world”進行實驗:
$ sudo bpftrace -e 'BEGIN { printf("hello world\n"); }'
注意,出于特權級的需要,你必須使用 root 運行 bpftrace,使用 -e 選項指明一個程序,構建一個所謂的“單行程序”。這個例子只會打印 “hello world”,接著等待你按下 Ctrl+C。
BEGIN 是一個特殊的探針名,只在執(zhí)行一開始生效一次;每次探針命中時,大括號 {} 內的操作(這個例子中只是一個 printf)
都會執(zhí)行。
現在讓我們轉向一個更有用的例子:
$ sudo bpftrace -e 't:syscalls:sys_enter_execve { printf("%s called %s\n", comm, str(args->filename)); }'
這個例子打印了父進程的名字(comm)和系統(tǒng)中正在創(chuàng)建的每個新進程的名稱。t:syscalls:sys_enter_execve 是一個內核追蹤點,是 tracepoint:syscalls:sys_enter_execve 的簡寫,兩種形式都可以使用。下一部分會向你展示如何列出所有可用的追蹤點。
comm 是一個 bpftrace 內建指令,代表進程名;filename 是 t:syscalls:sys_enter_execve 追蹤點的一個字段,這些字段可以通過 args 內建指令訪問。
追蹤點的所有可用字段可以通過這個命令列出:
bpftrace -lv "t:syscalls:sys_enter_execve"
示例用法
bpftrace 的一個核心概念是探針點,即 eBPF 程序可以連接到的(內核或用戶空間的)代碼中的測量點,可以分成以下幾大類:
所有可用的 kprobe / kretprobe、tracepoints、software 和 hardware 探針可以通過這個命令列出:
$ sudo bpftrace -l
uprobe / uretprobe 和 usdt 是用戶空間探針,專用于某個可執(zhí)行文件。要使用這些探針,通過下文中的特殊語法。profile 和 interval 探以固定的時間間隔觸發(fā);固定的時間間隔不在本文的范疇內。
映射 是保存計數、統(tǒng)計數據和柱狀圖的特殊 BPF 數據類型,你可以使用映射統(tǒng)計每個系統(tǒng)調用正在被調用的次數:
$ sudo bpftrace -e 't:syscalls:sys_enter_* { @[probe] = count(); }'
一些探針類型允許使用通配符匹配多個探針,你也可以使用一個逗號隔開的列表為一個操作塊指明多個連接點。上面的例子中,操作塊連接到了所有名稱以 t:syscalls:sysenter_ 開頭的追蹤點,即所有可用的系統(tǒng)調用。
bpftrace 的內建函數 count() 統(tǒng)計系統(tǒng)調用被調用的次數;@[] 代表一個映射(一個關聯(lián)數組)。該映射的鍵 probe 是另一個內建指令,代表完整的探針名。
這個例子中,相同的操作塊連接到了每個系統(tǒng)調用,之后每次有系統(tǒng)調用被調用時,映射就會被更新,映射中和系統(tǒng)調用對應的項就會增加。程序終止時,自動打印出所有聲明的映射。
下面的例子統(tǒng)計所有的系統(tǒng)調用,然后通過 bpftrace 過濾語法使用 PID 過濾出某個特定進程調用的系統(tǒng)調用:
$ sudo bpftrace -e 't:syscalls:sys_enter_* / pid == 1234 / { @[probe] = count(); }'
進程寫的字節(jié)數
讓我們使用上面的概念分析每個進程正在寫的字節(jié)數:
$ sudo bpftrace -e 't:syscalls:sys_exit_write /args->ret > 0/ { @[comm] = sum(args->ret); }'
bpftrace 連接操作塊到寫系統(tǒng)調用的返回探針(t:syscalls:sys_exit_write),然后使用過濾器丟掉代表錯誤代碼的負值(/arg->ret > 0/)。
映射的鍵 comm 代表調用系統(tǒng)調用的進程名;內建函數 sum() 累計每個映射項或進程寫的字節(jié)數;args 是一個 bpftrace 內建指令,用于訪問追蹤點的參數和返回值。如果執(zhí)行成功,write 系統(tǒng)調用返回寫的字節(jié)數,arg->ret
用于訪問這個字節(jié)數。
進程的讀取大小分布(柱狀圖):
bpftrace 支持創(chuàng)建柱狀圖。讓我們分析一個創(chuàng)建進程的 read 大小分布的柱狀圖的例子:
$ sudo bpftrace -e 't:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'
柱狀圖是 BPF 映射,因此必須保存為一個映射(@),這個例子中映射鍵是 comm。
這個例子使 bpftrace 給每個調用 read 系統(tǒng)調用的進程生成一個柱狀圖。要生成一個全局柱狀圖,直接保存 hist() 函數到 @(不使用任何鍵)。
程序終止時,bpftrace 自動打印出聲明的柱狀圖。創(chuàng)建柱狀圖的基準值是通過 args->ret 獲取到的讀取的字節(jié)數。
追蹤用戶空間程序
你也可以通過 uprobes / uretprobes 和 USDT(用戶級靜態(tài)定義的追蹤)追蹤用戶空間程序。下一個例子使用探測用戶級函數結尾處的 uretprobe ,獲取系統(tǒng)中運行的每個 bash 發(fā)出的命令行:
$ sudo bpftrace -e 'uretprobe:/bin/bash:readline { printf("readline: \"%s\"\n", str(retval)); }'
要列出可執(zhí)行文件 bash 的所有可用 uprobes / uretprobes, 執(zhí)行這個命令:
$ sudo bpftrace -l "uprobe:/bin/bash"
uprobe 指向用戶級函數執(zhí)行的開始,uretprobe 指向執(zhí)行的結束(返回處);readline() 是 /bin/bash 的一個函數,返回鍵入的命令行;retval 是被探測的指令的返回值,只能在 uretprobe 訪問。
使用 uprobes 時,你可以用 arg0..argN 訪問參數。需要調用 str() 將 char * 指針轉化成一個字符串。
自帶腳本
bpftrace 軟件包附帶了許多有用的腳本,可以在 /usr/share/bpftrace/tools/ 目錄找到。
這些腳本中,你可以找到:
你可以直接使用這些腳本,比如:
$ sudo /usr/share/bpftrace/tools/killsnoop.bt
你也可以在創(chuàng)建新的工具時參考這些腳本。
以上就是“Linux下怎么使用Bpftrace”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。