天天看點

eBPF監控工具bcc系列三自定義工具trace 1.   核心tracepoints 2.   第三方庫 3.   進階過濾

上篇中是通用的直接可用工具。

  trace工具可以指定跟蹤函數并顯示,可控制其輸出格式來顯示函數參數和傳回值。

例如跟蹤檔案擁有者的屬性更改,也就是跟蹤三個檔案系統調用chown,fchown,lchown。使用如下:

trace.py   

'p::SyS_chown "file = %s, to_uid = %d, to_gid = %d, from_uid =

%d", arg1, arg2, arg3, $uid'   

'p::SyS_fchown "fd = %d, to_uid = %d, to_gid = %d, from_uid =

'p::SyS_lchown "file = %s, to_uid = %d, to_gid = %d, from_uid =

%d", arg1, arg2, arg3, $uid'

例如跟蹤非主動上下文切換。

trace.py -p 1134138 't:sched:sched_switch

(args->prev_state == TASK_STATE_MAX || args->prev_state == 0)'

跟蹤系統中所有exec調用

# trace 'sys_execve "%s", arg1'

其中sys_execve是核心函數,%s表示列印字元串,這個被複制為arg1就是程式的入參。

例如跟蹤系統讀操作read,所讀大小大于20000(這個參數可以通過man read檢視是在第三個位置上),是以跟蹤函數如下:

trace 'sys_read (arg3 > 20000) "read %d

bytes", arg3'

還可以跟蹤使用者層函數,例如跟蹤bash上readline腳本,并輸出傳回值,可以如下書寫

trace 'r:bash:readline "%s", retval'

其中r表示retprobe是傳回探針。

跟蹤讀寫失敗的指令

trace 'r:c:read ((int)retval < 0) "read

failed: %d", retval' 'r:c:write ((int)retval < 0) "write failed:

%d", retval' -T

1.  

核心tracepoints

還可以跟蹤核心的tracepoints,例如跟蹤block:block_rq_complete的tracepoint,并列印多少扇區被傳輸。

trace 't:block:block_rq_complete

"sectors=%d", args->nr_sector' -T

如果不清楚跟蹤點的資料結構格式,可以使用tplist工具來獲得,例如

tplist -v block:block_rq_complete

得到資料結構後就可以用做參數來擷取nr_sector了。

2.  

第三方庫

越來越多進階庫支援探針,就像核心tracepoint一樣可以用來被跟蹤。

例如跟蹤pthread_create函數

trace 'u:pthread:pthread_create "%U", arg3'

-T -C

            其中%U表示将arg3解析成使用者層符号。同樣,核心的是%K.

            現在Ruby,Node,OpenJDK都支援。

跟蹤ruby示例:

trace 'u:ruby:method__entry "%s.%s", arg1,

arg2' -p $(pidof irb) -T

跟蹤共享庫函數如下:

trace.py 'r:/usr/lib64/libtinfo.so:curses_version

"Version=%s", retval'

3.  

進階過濾

跟蹤open,同時指出其打開的檔案名字為test.txt

trace 'p:c:open (STRCMP("test.txt", arg1))

"opening %s", arg1' -T

trace 'p::SyS_nanosleep(struct timespec *ts)

"sleep for %lld ns", ts->tv_nsec'

跟蹤指定程序的指定函數,使用-p參數,如下:

trace

-p 2740 'do_sys_open "%s", arg2' -T