標籤:put 線性 輸出 描述 資料 大小 with ali 核心
eBPF監控工具bcc系列九bcc Python
接下來看下python方面的知識。
1. 初始化1.1 BPF
文法:
BPF({text=BPF_program | src_file=filename} [, usdt_contexts=[USDT_object, ...]])
建立一個BPF對象,能通過互動來產生輸出。
1.2 USDT
文法:USDT({pid=pid | path=path})
建立對象來使用USDT,可以指定進程ID,路徑。
2. 事件2.1 attach_kprobe
文法:
BPF.attach_kprobe(event="event", fn_name="name")
使用函數入口的核心動態跟蹤,關聯C函數name和核心功能event()。
2.2 attach_kretprobe
文法:
BPF.attach_kretprobe(event="event", fn_name="name")
關聯C函數name和核心功能event,在核心功能返回的時候調用函數name.
2.3 attach_tracepoint
文法:
BPF.attach_tracepoint(tp="tracepoint", fn_name="name")
關聯C語言定義的BPF函數和核心的tracepoint。也可以使用TRACEPOINT_PROBE宏,使用該宏可以使用進階的自申明的args結構體包含了tracepoint參數。如果,使用attach_tracepoint,參數需要在BPF程式中聲明。
2.4 attach_uprobe
文法:
BPF.attach_uprobe(name="location", sym="symbol", fn_name="name")
將在location中的函數事件symbol,關聯到C定義的函數。當symbol調用時候回調用name函數。
例如:
b.attach_uprobe(name="c", sym="strlen", fn_name="count")
2.5 attach_uretprobe
文法:
BPF.attach_uretprobe(name="location", sym="symbol", fn_name="name")
同attach_uprobe,不過是在函數返回時候調用name函數。
2.6 USDT.enable_probe
文法:
USDT.enable_probe(probe=probe, fn_name=name)
將BPF的C函數附加到USDT探針上。
例如:
u = USDT(pid=int(pid))u.enable_probe(probe="http__server__request", fn_name="do_trace")
查看二進位檔案是否有USDT探針,可以使用如下命令檢測stap調試段:
#readelf –n binary
3. 調試輸出3.1 trace_print
文法:
BPF.trace_print(fmt="fields")
持續讀取全域共用的/sys/kernel/debug/tracing/trace_pipe檔案並輸出。這個檔案可以被BPF 和bpf_trace_printk()函數寫入。
例如:
# print trace_pipe output as-is:b.trace_print()# print PID and message:b.trace_print(fmt="{1} {5}")
3.2 trace_fields
文法:BPF.trace_fields(nonblocking=False)
從全域共用檔案/sys/kernel/debug/tracing/trace_pipe檔案中讀取一行並返回域。參數表示在等待寫入的時候是否blocking.
4. 輸出4.1 perf_buffer_poll
文法:
BPF.perf_buffer_poll()
從perf ring buffers等待資料,有資料會調用open_perf_buffer指定的回呼函數。
例如:
# loop with callback to print_eventb["events"].open_perf_buffer(print_event)while 1: b.perf_buffer_poll()
5. 映射5.1 get_table
返回表對象。此函數已經淘汰,因為BFP可以將表作為items來讀取,例如BFP[name].
5.2 open_perf_buffer
文法:
table.open_perf_buffers(callback, page_cnt=N, lost_cb=None)
當perf ring buffer中資料可用的時候,調用callback函數。其中table是定義在BPF的。這個是從核心到使用者層傳遞perf event資料的建議方式。
perf ring buffer的大小由page_cnt參數制定,建議是頁的偶數倍,預設是8。如果callback處理的不夠快,有些資料會丟失掉。當有遺失資料到時候會調用lost_cb。如果lost_cb定義為none,那麼會列印一行資訊到stderr。
5.3 items
返回表中keys的數組。可以通過BPF_HASH來擷取,迭代。
5.4 values
返回表中values數組。
5.5 clear
清除表。
5.6 print_log2_hist
文法:table.print_log2_hist(val_type="value", section_header="Bucket ptr", section_print_fn=None)
使用ASCII以log2長條圖列印表。表必須用log2方式儲存,這個可以通過bpf_log2()。
val_type可選的,表示列頭。
section_header:如果長條圖有第二個鍵,多個表會被列印,section_header會被作為頭描述。
如果section_print_fn不是none,傳遞bucket值。
5.7 print_linear_hist
文法:
table.print_linear_hist(val_type="value", section_header="Bucket ptr", section_print_fn=None)
以ASCII方式列印表的線性長條圖。
val_type參數可選的,列的頭
section_header:如果長條圖有第二個鍵,多個圖會列印,section_header會被作為頭描述符。
section_print_fn:如果該參數不會NONE,會被傳遞bucket值。
6. 協助6.1 ksym
文法:
BPF.ksym(addr)
將一個核心記憶體位址轉成一個核心功能名字。
6.2 ksymname
文法:
BPF.ksymname(name)
將一個核心名字轉換成一個地址,是ksym的逆向函數。
6.3 sym
文法:
BPF.sym(addr, pid, show_module=False, show_offset=False)
為進程轉換一個記憶體位址位函數名字。
參數show_module,show_offset參數控制是否顯示symbol符號所在的模組,符號位移。
6.4 num_open_kprobes
返回開啟的k[ret]probes數量。在event_re情境中有用。
7. 關於BPF Errors
BPF中所有記憶體讀取都要通過bpf_probe_read()函數將記憶體複製到BPF棧。如果直接讀取記憶體,會出現Invalid mem access。
參考檔案:
核心中Documentation/networking/filter.txt
eBPF監控工具bcc系列九bcc Python