上篇中是通用的直接可用工具。
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