日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Linux內(nèi)核調(diào)試工具 Ftrace 進(jìn)階使用手冊(cè)

 老匹夫 2016-01-26
Ftrace 是一個(gè)內(nèi)核中的追蹤器,用于幫助系統(tǒng)開(kāi)發(fā)者或設(shè)計(jì)者查看內(nèi)核運(yùn)行情況,它可以被用來(lái)調(diào)試或者分析延遲/性能問(wèn)題。最早 ftrace 是一個(gè) function tracer,僅能夠記錄內(nèi)核的函數(shù)調(diào)用流程。如今 ftrace 已經(jīng)成為一個(gè)framework,采用 plugin 的方式支持開(kāi)發(fā)人員添加更多種類(lèi)的 trace 功能。


一、Ftrace 的內(nèi)核配置

ftrace 相關(guān)的配置選項(xiàng)列表
     CONFIG_FUNCTION_TRACER
     CONFIG_FUNCTION_GRAPH_TRACER
     CONFIG_CONTEXT_SWITCH_TRACER
     CONFIG_NOP_TRACER

     CONFIG_SCHED_TRACER


在內(nèi)核的Menuconfig中查看更加直觀:
    Kernel hacking  --->
        Tracers ─>
            [*]   Kernel Function Tracer
            [*]     Kernel Function Graph Tracer (NEW)

            ...  (下面還有幾個(gè)追蹤器的選項(xiàng),可以根據(jù)自己的需要選擇)


注: 如果是在 32 位 x86 機(jī)器上,編譯時(shí)不要選中 General setup 菜單項(xiàng)下的 Optimize for size 選項(xiàng),否則就無(wú)法看到 Kernel Function Graph Tracer 選項(xiàng)。這是因?yàn)樵?Konfig 文件中,針對(duì) 32 位 x86 機(jī)器,表項(xiàng) FUNCTION_GRAPH_TRACER 有一個(gè)特殊的依賴(lài)條件:

             depends on !X86_32 || !CC_OPTIMIZE_FOR_SIZE


Ftrace 通過(guò) debugfs 向用戶(hù)態(tài)提供了訪問(wèn)接口,所以還需要將 debugfs 編譯進(jìn)內(nèi)核。激活對(duì) debugfs 的支持,可以直接編輯內(nèi)核配置文件 .config ,設(shè)置CONFIG_DEBUG_FS=y ;或者在 make menuconfig 時(shí)到 Kernel hacking 菜單下選中對(duì) debugfs 文件系統(tǒng)的支持:
    Kernel hacking  --->

        -*- Debug Filesystem


二、Ftrace 的基本使用步驟



2.1. 掛載Debugfs:

Ftrace 通過(guò) debugfs 向用戶(hù)態(tài)提供訪問(wèn)接口。配置內(nèi)核時(shí)激活 debugfs 后會(huì)創(chuàng)建目錄 /sys/kernel/debug ,debugfs 文件系統(tǒng)就是掛載

到該目錄。


2.1.1 運(yùn)行時(shí)掛載:

官方掛載方法 :
mount -t debugfs nodev /sys/kernel/debug
我覺(jué)得自己建一個(gè) /debug 文件夾,掛載在這個(gè)路徑下使用比較方便:
# mkdir /debug
# mount -t debugfs nodev /debug
# cd /debug/tracing                    // debugfs掛載路徑下的tracing 才是 ftrace 的“大本營(yíng)”!

或者我們可以使用官方掛載辦法后建立一個(gè)軟連接:

mount -t debugfs nodev /sys/kernel/debug
        # ln -s /sys/kernel/debug  /debug 


2.1.2 系統(tǒng)啟動(dòng)自動(dòng)掛載:

要在系統(tǒng)啟動(dòng)自動(dòng)掛載debugfs,需要將如下內(nèi)容添加到 /etc/fstab 文件:
        debugfs  /sys/kernel/debug  debugfs  defaults  0  0


2.2. 選擇一種 tracer:

# cat current_tracer           // 查看當(dāng)前追蹤器
nop   // no option
# cat available_tracers      // 查看當(dāng)前內(nèi)核中可用跟蹤器
blk function_graph function nop
# echo function_graph > current_tracer        // 我們選用 function_graph 追蹤器


2.3. 打開(kāi)關(guān)閉追蹤

在老一點(diǎn)版本的內(nèi)核上tracing目錄下有tracing_enabled,需要給tracing_enabled和tracing_on同時(shí)賦值 1 才能打開(kāi)追蹤,而在比較新的內(nèi)核上已經(jīng)去掉 tracing_enabled ,我們只需要控制tracing_on 即可打開(kāi)關(guān)閉追蹤。

#echo 1 > tracing_on             // 打開(kāi)跟蹤

# echo 0 > tracing_on             // 關(guān)閉跟蹤

# echo 1 > tracing_on; run_test; echo 0 > tracing_on          //  打開(kāi)跟蹤后做一件事再關(guān)閉跟蹤,所以此次跟蹤的結(jié)果基本上是這個(gè)運(yùn)行的程序的跟蹤結(jié)果,但是肯定會(huì)包括很多雜訊,所以后面會(huì)介紹跟蹤某個(gè) pid 的或者跟蹤某個(gè)函數(shù)。

注:對(duì)于為什么去掉 tracing_enabled 我問(wèn)過(guò) Ftrace 的維護(hù)人Steven Rostedt,他說(shuō)使用 tracing_on 可以快速的打開(kāi) Ftrace 的追蹤,這讓 tracing_enabled 顯得很輕量級(jí)或者說(shuō)顯得比較冗余,下面可以會(huì)說(shuō)到,我們寫(xiě)內(nèi)核程序時(shí)可以使用Ftrace 提供的內(nèi)核函數(shù) tracing_on() or tracing_off() 直接打開(kāi)追蹤,這其實(shí)就是使用的 tracing_on ,所以在新內(nèi)核中 tracing_enabled 這個(gè)看起來(lái)比較冗余的選項(xiàng)已經(jīng)被刪除。


2.4. 查看追蹤結(jié)果

ftrace 的輸出信息主要保存在 3 個(gè)文件中。
*   trace,該文件保存 ftrace 的輸出信息,其內(nèi)容可以直接閱讀。
*   latency_trace,保存與 trace 相同的信息,不過(guò)組織方式略有不同。主要為了用戶(hù)能方便地分析系統(tǒng)中有關(guān)延遲的信息。
*   trace_pipe 是一個(gè)管道文件,主要為了方便應(yīng)用程序讀取 trace 內(nèi)容。算是擴(kuò)展接口吧。


所以可以直接查看 trace 追蹤文件,也可以在追蹤之前使用trace_pipe 將追蹤結(jié)果直接導(dǎo)向其他的文件。
比如: # cat trace_pipe > /tmp/log &     // 使用trace_pipe 將跟蹤結(jié)果導(dǎo)入 /tmp/log 里,我們可以直接 “ cat /tmp/log” 查看跟蹤信息。
當(dāng)然也可以直接查看trace文件 #cat trace 或者使用 cat trace  > /tmp/log 將跟蹤信息導(dǎo)入 /tmp/log


三、 Ftrace 的進(jìn)階使用:

3.1. 追蹤指定的進(jìn)程

使用 echo pid > set_ftrace_pid  來(lái)追蹤指定的進(jìn)程!
我們寫(xiě)程序時(shí)可以使用getpid 獲取進(jìn)程PID,然后使用 write 將pid 寫(xiě)入 /debug/tracing/set_ftrace_pid ,并使用write 寫(xiě)1 到 tracing_on 打開(kāi)追蹤(因?yàn)樵谟脩?hù)空間使用不了tracing_on函數(shù)),此時(shí)即可追蹤當(dāng)前這個(gè)進(jìn)程。

3.2. 追蹤事件:

3.2.1 首先查看事件文件夾下面有哪些選項(xiàng)

# ls events/
block    ext4    header_event  jbd2 napi  raw_syscalls…… enable
# ls events/sched/
enable    sched_kthread_stop_ret  sched_process_exit sched_process_wait ……


3.2.2 追蹤一個(gè)/若干事件

# echo 1 > events/sched/sched_wakeup/enable

                ...(省略追蹤過(guò)程)
# cat trace | head -10
# tracer: nop
#TASK-PID  CPU#  TIMESTAMP    FUNCTION
# || | |
bash-2613 [001] 425.078164: sched_wakeup: task bash:2613 [120] success=0 [001]
bash-2613 [001] 425.078184: sched_wakeup: task bash:2613 [120] success=0 [001]
...


3.2.3 追蹤一類(lèi)事件

# echo 1 > events/sched/enable

                ... 
# cat trace | head -10
# tracer: nop
#TASK-PID            CPU#  TIMESTAMP    FUNCTION
#   |                           |                |                     | 
events/0-9               [000]   638.042792:   sched_switch: task events/0:9 [120] (S) ==> kondemand/0:1305 [120]
ondemand/0-1305   [000]    638.042796:  sched_stat_wait: task: restorecond:1395 wait: 15023 [ns]
...


3.2.4 追蹤所有事件

# echo 1 > events/enable

                ...
# cat trace | head -10
# tracer: nop
#TASK-PID     CPU#     TIMESTAMP    FUNCTION
#   |                    |                    |                   | 
cpid-1470       [001]   794.947181:         kfree: call_site=ffffffff810c996d ptr=(null)
acpid-1470     [001] 794.947182:      sys_read -> 0x1
acpid-1470     [001]   794.947183:      sys_exit: NR 0 = 1
...


3.3. stack_trace

# echo 1 > /proc/sys/kernel/stack_tracer_enabled
OR # kernel command line “stacktrace”
查看: # cat stack_trace


3.4. 設(shè)置追蹤過(guò)濾器

將要跟蹤的函數(shù)寫(xiě)入文件 set_ftrace_filter ,將不希望跟蹤的函數(shù)寫(xiě)入文件 set_ftrace_notrace。通常直接操作文件 set_ftrace_filter 就可以了. 


四、 Ftrace 提供的函數(shù)使用

內(nèi)核頭文件 include/linux/kernel.h 中描述了 ftrace 提供的工具函數(shù)的原型,這些函數(shù)包括 trace_printk、tracing_on/tracing_off 等。


4.1. 使用 trace_printk 打印跟蹤信息

ftrace 提供了一個(gè)用于向 ftrace 跟蹤緩沖區(qū)輸出跟蹤信息的工具函數(shù),叫做 trace_printk(),它的使用方式與 printk() 類(lèi)似。可以通過(guò) trace 文件讀取該函數(shù)的輸出。從頭文件 include/linux/kernel.h 中可以看到,在激活配置 CONFIG_TRACING 后,trace_printk() 定義為宏:
     #define trace_printk(fmt, args...)  
        ...
所以在使用時(shí):(例子是在一個(gè)內(nèi)核模塊中添加打印信息)
  1. #include <linux/init.h>   
  2.  #include <linux/module.h>   
  3.  #include <linux/kernel.h>   
  4.   
  5.  MODULE_LICENSE("GPL");   
  6.   
  7.  static int ftrace_demo_init(void)   
  8.  {   
  9.      trace_printk("Can not see this in trace unless loaded for the second time\n");   
  10.      return 0;   
  11.  }   
  12.   
  13.  static void ftrace_demo_exit(void)   
  14.  {   
  15.      trace_printk("Module unloading\n");   
  16.  }   
  17.   
  18.  module_init(ftrace_demo_init);   
  19.  module_exit(ftrace_demo_exit);  


4.2. 使用 tracing_on/tracing_off 控制跟蹤信息的記錄

在跟蹤過(guò)程中,有時(shí)候在檢測(cè)到某些事件發(fā)生時(shí),想要停止跟蹤信息的記錄,這樣,跟蹤緩沖區(qū)中較新的數(shù)據(jù)是與該事件有關(guān)的。在用戶(hù)態(tài),可以通過(guò)向文件 tracing_on 寫(xiě)入 0 來(lái)停止記錄跟蹤信息,寫(xiě)入 1 會(huì)繼續(xù)記錄跟蹤信息。而在內(nèi)核代碼中,可以通過(guò)函數(shù) tracing_on() 和 tracing_off() 來(lái)做到這一點(diǎn),它們的行為類(lèi)似于對(duì) /sys/kernel/debug/tracing 下的文件 tracing_on 分別執(zhí)行寫(xiě) 1 和 寫(xiě) 0 的操作。
使用這兩個(gè)函數(shù),會(huì)對(duì)跟蹤信息的記錄控制地更準(zhǔn)確一些,這是因?yàn)樵谟脩?hù)態(tài)寫(xiě)文件 tracing_on 到實(shí)際暫停跟蹤,中間由于上下文切換、系統(tǒng)調(diào)度控制等可能已經(jīng)經(jīng)過(guò)較長(zhǎng)的時(shí)間,這樣會(huì)積累大量的跟蹤信息,而感興趣的那部分可能會(huì)被覆蓋掉了。


實(shí)際代碼中,可以通過(guò)特定條件(比如檢測(cè)到某種異常狀況,等等)來(lái)控制跟蹤信息的記錄,函數(shù)的使用方式類(lèi)似如下的形式:
 if (condition) 
tracing_on() or tracing_off()

跟蹤模塊運(yùn)行狀況時(shí),使用 ftrace 命令操作序列在用戶(hù)態(tài)進(jìn)行必要的設(shè)置,而在代碼中則可以通過(guò) traceing_on() 控制在進(jìn)入特定代碼區(qū)域時(shí)開(kāi)啟跟蹤信息,并在遇到某些條件時(shí)通過(guò) tracing_off() 暫停;讀者可以在查看完感興趣的信息后,將 1 寫(xiě)入 tracing_on 文件以繼續(xù)記錄跟蹤信息。實(shí)踐中,可以通過(guò)宏來(lái)控制是否將對(duì)這些函數(shù)的調(diào)用編譯進(jìn)內(nèi)核模塊,這樣可以在調(diào)試時(shí)將其開(kāi)啟,在最終發(fā)布時(shí)將其關(guān)閉。
用戶(hù)態(tài)的應(yīng)用程序可以通過(guò)直接讀寫(xiě)文件 tracing_on 來(lái)控制記錄跟蹤信息的暫停狀態(tài),以便了解應(yīng)用程序運(yùn)行期間內(nèi)核中發(fā)生的活動(dòng)。


五、 簡(jiǎn)單的 Ftrace 腳本案例:

我在下面使用一個(gè)腳本執(zhí)行 Ftrace 的操作,自動(dòng)追蹤 HelloWorld 程序執(zhí)行:

[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. #!/bin/bash  
  2. debugfs_path=/debug                       
  3. ftrace_call_path=$debugfs_path/tracing  
  4. app_path=/home/dslab/test  
  5.   
  6. # 測(cè)試我們的 /debug 路徑是否已經(jīng)建立  
  7. if ! test -d $debugfs_path; then  
  8.         echo "I'll create the directory /debug"  
  9.         mkdir $debugfs_path  
  10. else echo "Hum ,the /debug directory is standing by"  
  11. fi   
  12.   
  13. # 測(cè)試debugfs是否已經(jīng)掛載  
  14. mount | grep "debugfs" > /dev/null  
  15. if [ $? != 0 ]; then  
  16.         echo "we have not mount debugfs"  
  17.         mount -t debugfs nodev $debugfs_path  
  18. else echo "yeah,debugfs has been mounted"  
  19. fi  
  20.   
  21. # 測(cè)試ftrace 是否可用  
  22. if ! test -d $ftrace_call_path; then  
  23.         echo "sorry, may be your kernel is not support for the ftrace"  
  24.         exit -1;  
  25. else echo "Hum ,Ftrace is standing by"  
  26. fi        
  27. # 將目前的trace 文件清空  
  28. echo "" >  $ftrace_call_path/trace  
  29. # 選擇 function_graph 跟蹤器  
  30. echo "function_graph" > $ftrace_call_path/current_tracer  
  31. # 我的Debian7 使用的3.2 內(nèi)核上還有tracing_enabled ,先給它賦值 1  
  32. echo 1 > $ftrace_call_path/tracing_enabled  
  33. # 使用 trace_pipe 將追蹤結(jié)果重定向到/tmp/result(后臺(tái)運(yùn)行,使得下面的步驟得以進(jìn)行)  
  34. cat $ftrace_call_path/trace_pipe > /tmp/result &  
  35. # 打開(kāi)追蹤  
  36. echo 1 > $ftrace_call_path/tracing_on  
  37. # 我在這里執(zhí)行了一個(gè)已經(jīng)編譯好helloworld 程序  
  38. exec $app_path/hello  
  39. # 關(guān)閉追蹤  
  40. echo 0 > $ftrace_call_path/tracing_on  

運(yùn)行效果如下:

[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. dslab@wheezy:~$ sudo ./ftrace.sh  
  2. [sudo] password for dslab:   
  3. Hum ,the /debug directory is standing by  
  4. yeah,debugfs has been mounted  
  5. Hum ,Ftrace is standing by  
  6. Hello World  
  7. dslab@wheezy:~$   


===================================

參考資料:

【1】Linux內(nèi)核中的ftrace 文檔,路徑為:linux-source-3.2/Documentation/trace/ftrace.txt (還有個(gè)ftrace-design.txt也很值得學(xué)習(xí))

【2】ftrace 簡(jiǎn)介 :   http://www.ibm.com/developerworks/cn/linux/l-cn-ftrace/

【3】使用 ftrace 調(diào)試 Linux 內(nèi)核:
            part1   :   http://www.ibm.com/developerworks/cn/linux/l-cn-ftrace1/
            part2   :   http://www.ibm.com/developerworks/cn/linux/l-cn-ftrace2/
            part3   :   http://www.ibm.com/developerworks/cn/linux/l-cn-ftrace3/


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多