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

分享

使用 ftrace 調(diào)試 Linux 內(nèi)核,第 3 部分

 老匹夫 2014-02-06

內(nèi)核頭文件 include/linux/kernel.h 中描述了 ftrace 提供的工具函數(shù)的原型,這些函數(shù)包括 trace_printk、tracing_on/tracing_off 等。本文通過示例模塊程序向讀者展示如何在代碼中使用這些工具函數(shù)。

使用 trace_printk 打印跟蹤信息

ftrace 提供了一個用于向 ftrace 跟蹤緩沖區(qū)輸出跟蹤信息的工具函數(shù),叫做 trace_printk(),它的使用方式與 printk() 類似。可以通過 trace 文件讀取該函數(shù)的輸出。從頭文件 include/linux/kernel.h 中可以看到,在激活配置 CONFIG_TRACING 后,trace_printk() 定義為宏:

     #define trace_printk(fmt, args...)   		 \ 
        ...

下面通過一個示例模塊 ftrace_demo 來演示如何使用 trace_printk() 向跟蹤緩沖區(qū)輸出信息,以及如何查看這些信息。這里的示例模塊程序中僅提供了初始化和退出函數(shù),這樣讀者不會因為需要為模塊創(chuàng)建必要的訪問接口比如設(shè)備文件而分散注意力。注意,編譯模塊時要加入 -pg 選項。

清單 1. 示例模塊 ftrace_demo
 /*                                                     
 * ftrace_demo.c 
 */                                                    
 #include <linux/init.h> 
 #include <linux/module.h> 
 #include <linux/kernel.h> 

 MODULE_LICENSE("GPL"); 

 static int ftrace_demo_init(void) 
 { 
	 trace_printk("Can not see this in trace unless loaded for the second time\n"); 
	 return 0; 
 } 

 static void ftrace_demo_exit(void) 
 { 
	 trace_printk("Module unloading\n"); 
 } 

 module_init(ftrace_demo_init); 
 module_exit(ftrace_demo_exit);

示例模塊非常簡單,僅僅是在模塊初始化函數(shù)和退出函數(shù)中輸出信息。接下來要對模塊的運行進行跟蹤,如清單 2 所示。

清單 2. 對模塊 ftrace_demo 進行跟蹤
 [root@linux tracing]# pwd 
 /sys/kernel/debug/tracing 
 [root@linux tracing]# echo 0 > tracing_enabled 
 [root@linux tracing]# echo 1 > /proc/sys/kernel/ftrace_enabled 
 [root@linux tracing]# echo function_graph > current_tracer 

 # 事先加載模塊 ftrace_demo 

 [root@linux tracing]# echo ':mod:ftrace_demo' > set_ftrace_filter 
 [root@linux tracing]# cat set_ftrace_filter 
 ftrace_demo_init 
 ftrace_demo_exit 

 # 將模塊 ftrace_demo 卸載

 [root@linux tracing]# echo 1 > tracing_enabled 

 # 重新進行模塊 ftrace_demo 的加載與卸載操作

 [root@linux tracing]# cat trace 
 # tracer: function_graph 
 # 
 # CPU  DURATION                  FUNCTION CALLS 
 # |     |   |                     |   |   |   | 
 1)               |  /* Can not see this in trace unless loaded for the second time */ 
 0)               |  /* Module unloading */

在這個例子中,使用 mod 指令顯式指定跟蹤模塊 ftrace_demo 中的函數(shù),這需要提前加載該模塊,否則在寫文件 set_ftrace_filter 時會因為找不到該模塊報錯。這樣在第一次加載模塊時,其初始化函數(shù) ftrace_demo_init 中調(diào)用 trace_printk 打印的語句就跟蹤不到了。因此這里會將其卸載,然后激活跟蹤,再重新進行模塊 ftrace_demo 的加載與卸載操作。最終可以從文件 trace 中看到模塊在初始化和退出時調(diào)用 trace_printk() 輸出的信息。

這里僅僅是為了以簡單的模塊進行演示,故只定義了模塊的 init/exit 函數(shù),重復加載模塊也只是為了獲取初始化函數(shù)輸出的跟蹤信息。實踐中,可以在模塊的功能函數(shù)中加入對 trace_printk 的調(diào)用,這樣可以記錄模塊的運作情況,然后對其特定功能進行調(diào)試優(yōu)化。還可以將對 trace_printk() 的調(diào)用通過宏來控制編譯,這樣可以在調(diào)試時將其開啟,在最終發(fā)布時將其關(guān)閉。

回頁首

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

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

現(xiàn)在對清單 1 中的代碼進行修改,使用 tracing_off() 來控制跟蹤信息記錄的暫停。

清單 3. 使用 tracing_off 的模塊 ftrace_demo
 /*                                                     
 * ftrace_demo.c 
 *     modified to demostrate the usage of tracing_off 
 */                                                    
 #include <linux/init.h> 
 #include <linux/module.h> 
 #include <linux/kernel.h> 

 MODULE_LICENSE("GPL"); 

 static int ftrace_demo_init(void) 
 { 		
	 trace_printk("ftrace_demo_init called\n"); 
	 tracing_off(); 
	 return 0; 
 } 

 static void ftrace_demo_exit(void) 
 { 
	 trace_printk("ftrace_demo_exit called\n"); 
	 tracing_off(); 
 } 

 module_init(ftrace_demo_init); 
 module_exit(ftrace_demo_exit);

下面對其進行跟蹤,如清單 4 所示。

清單 4. 跟蹤
 [root@linux tracing]# pwd 
 /sys/kernel/debug/tracing 
 [root@linux tracing]# echo 0 > tracing_enabled 
 [root@linux tracing]# echo 1 > /proc/sys/kernel/ftrace_enabled 
 [root@linux tracing]# echo 1 > tracing_on 
 [root@linux tracing]# echo function > current_tracer 
 [root@linux tracing]# echo 1 > tracing_enabled 

 # 加載模塊 ftrace_demo,模塊初始化函數(shù) ftrace_demo_init 被調(diào)用

 [root@linux tracing]# cat tracing_on 
 0 
 [root@linux tracing]# cat trace | wc -l 
 120210 
 [root@linux tracing]# cat trace | grep -n ftrace_demo_init 
 120187:      insmod-2897  [000]  2610.504611: ftrace_demo_init <-do_one_initcall 
 120193:      insmod-2897  [000]  2610.504667: ftrace_demo_init: ftrace_demo_init called 

 [root@linux tracing]# echo 1 > tracing_on   # 繼續(xù)跟蹤信息的記錄

 # 卸載模塊 ftrace_demo,模塊函數(shù) ftrace_demo_exit 被調(diào)用

 [root@linux tracing]# cat tracing_on 
 0 
 [root@linux tracing]# wc -l trace 
 120106 trace 
 [root@linux tracing]# grep -n ftrace_demo_exit trace 
 120106:           rmmod-2992  [001]  3016.884449: : ftrace_demo_exit called

在這個例子中,跟蹤開始之前需要確保 tracing_on 的值為 1。跟蹤開始后,加載模塊 ftrace_demo,其初始化方法 ftrace_demo_init 被調(diào)用,該方法會調(diào)用 tracing_off() 函數(shù)來暫停跟蹤信息的記錄,這時文件 tracing_on 的值被代碼設(shè)置為 0。查看文件 trace,可以看到 ftrace_demo_init 相關(guān)的記錄位于跟蹤信息的末端,這是因為從調(diào)用 trace_off() 到其生效需要一段時間,這段時間中的內(nèi)核活動會被記錄下來;相比從用戶態(tài)讀寫 tracing_on 文件,這段時間開銷要小了許多。卸載模塊時的情況與此類似。從這里可以看到,在代碼中使用 tracing_off() 可以控制將感興趣的信息保存在跟蹤緩沖區(qū)的末端位置,不會很快被新的信息所覆蓋,便于及時查看。

實際代碼中,可以通過特定條件(比如檢測到某種異常狀況,等等)來控制跟蹤信息的記錄,函數(shù)的使用方式類似如下的形式:

 if (condition) 
	 tracing_on() or tracing_off()

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

用戶態(tài)的應用程序可以通過直接讀寫文件 tracing_on 來控制記錄跟蹤信息的暫停狀態(tài),以便了解應用程序運行期間內(nèi)核中發(fā)生的活動。

回頁首

小結(jié)

本系列文章對 ftrace 的配置和使用進行了介紹。本文是其中的第三部分,通過示例代碼介紹了 ftrace 所提供的部分工具函數(shù)的使用,包括 trace_printk、tracing_on/tracing_off 。至此,本系列文章的所有內(nèi)容都已經(jīng)介紹完畢。通過本系列文章,讀者可以了解如何使用 ftrace 來對內(nèi)核進行調(diào)試和分析。ftrace 使用起來非常靈活,并且支持多種跟蹤器,而且它的框架結(jié)構(gòu)使得在添加新的跟蹤器的時候會比較方便。讀者可以在以后的工作和學習中探索 ftrace 的各種用法。

參考資料

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多