Linux/Android開發記錄
ftrace官方文件在kernel/Documentation/trace/ftrace.txt檔案中。
使用ftrace介面之前,如果系統沒有自動掛載debugfs檔案系統,則要先手動掛載。
# mount -t debugfs nodev /sys/kernel/debug
ftracer的目錄為/sys/kernel/debug/tracing,下面介紹這個目錄下的常用檔案:
tracing_on,啟用/禁用向追蹤緩衝區寫入功能。1為啟用,0為禁用。
available_tracers,當前核心中可用的外掛追蹤器。
current_tracer,指定當前要使用的外掛追蹤器。
tracing_cpumask,以十六進位制的位掩碼指定要作為追蹤物件的處理器,例如,指定0xb時僅在處理器0、1、3上進行追蹤。
set_ftrace_pid,指定作為追蹤物件的程序的PID號。
trace,以文字格式輸出核心中追蹤緩衝區的內容。
trace_pipe,與trace相同,但是執行時像管道一樣,可以在每次事件發生時讀出追蹤資訊,但是讀出的內容不能再次讀出。
buffer_size_kb,以KB為單位指定各個CPU追蹤緩衝區的大小。系統追蹤緩衝區的總大小就是這個值乘以CPU的數量。設定buffer_size_kb時,必須設定current_tracer為nop追蹤器。
set_ftrace_filter,指定要追蹤的函式名稱,函式名稱僅可以包含一個萬用字元。
set_ftrace_notrace,指定不要追蹤的函式名稱。
ftrace可以使用的外掛追蹤器主要有:
function,函式呼叫追蹤器,可以看出哪個函式何時呼叫。
function_graph,函式呼叫圖表追蹤器,可以看出哪個函式被哪個函式呼叫,何時返回。
mmiotrace,MMIO( Memory MappedI/O)追蹤器,用於Nouveau驅動程式等逆向工程。
blk,block I/O追蹤器。
wakeup,程序排程延遲追蹤器。
wakeup_rt,與wakeup相同,但以實時程序為物件。
irqsoff,當中斷被禁止時,系統無法響應外部事件,造成系統響應延遲,irqsoff跟蹤並記錄核心中哪些函式禁止了中斷,對於其中禁止中斷時間最長的,irqsoff將在log檔案的第一行標示出來,從而可以迅速定位造成系統響應延遲的原因。
preemptoff,追蹤並記錄禁止核心搶佔的函式,並清晰顯示出禁止核心搶佔時間最長的函式。
preemptirqsoff,追蹤並記錄禁止核心搶佔和中斷時間最長的函式。
sched_switch,進行上下文切換的追蹤,可以得知從哪個程序切換到了哪個程序。
nop,不執行任何操作。不使用外掛追蹤器時指定。
ftrace使用舉例:追蹤程序排程函式schedule是由哪個函式呼叫的。
1、 檢視available_tracers的內容,確定當前核心是否支援記錄函式呼叫的函式追蹤器:
[email protected]:/sys/kernel/debug/tracing# cat available_tracers
blk function_graph mmiotrace wakeup_rtwakeup function nop
可以看到,available_tracers中包含function,即函式追蹤器。
2、 一旦將函式追蹤器啟動,ftrace會記錄所有函式的執行情況,但是我們只想檢視schedule函式的呼叫情況,因此先設定函式過濾器,僅記錄schedule:
[email protected]:/sys/kernel/debug/tracing#echo schedule > set_ftrace_filter
3、 將函式追蹤器function寫入current_tracer檔案:
[email protected]:/sys/kernel/debug/tracing#echo function > current_tracer
4、 追蹤結果可以從trace檔案讀出:
[email protected]:/sys/kernel/debug/tracing#head trace
# tracer: function
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
bash-29903 [003] 262746.977929: schedule <-sysret_careful
kworker/3:1-239 [003]262746.977937: schedule <-worker_thread
<idle>-0 [000]262746.977940: schedule <-cpu_idle
bash-29903 [003] 262746.977943: schedule <-schedule_timeout
sshd-2562 [000] 262746.977994:schedule <-schedule_hrtimeout_range_clock
<idle>-0 [003]262746.979523: schedule <-cpu_idle
可以看出,bash, kworker,idle,sshd這幾個程序的相應函式呼叫了schedule函式。
可以使用多個函式名稱或萬用字元向過濾器指定模式、模組。例如:
[email protected]:/sys/kernel/debug/tracing#echo ‘irq*’ > set_ftrace_filter
可以記錄函式名以irq開頭的所有函式呼叫。
另外,在引數前面加上:mod:,可以僅追蹤指定模組中包含的函式(注意,模組必須已經載入)。例如:
[email protected]:/sys/kernel/debug/tracing# echo 'write*:mod:ext3' > set_ftrace_filter
僅追蹤ext3模組中包含的以write開頭的函式。
要清空trace的內容執行如下命令:
# echo 0 > tracing_on
# echo 0 > trace
# cat trace
trace_printk列印除錯資訊後,將current_tracer設定為nop,將tracing_on設定為1,呼叫相應模組執行,即可通過trace檔案看到trace_printk列印的資訊。