开心六月综合激情婷婷|欧美精品成人动漫二区|国产中文字幕综合色|亚洲人在线成视频

    1. 
      
        <b id="zqfy3"><legend id="zqfy3"><fieldset id="zqfy3"></fieldset></legend></b>
          <ul id="zqfy3"></ul>
          <blockquote id="zqfy3"><strong id="zqfy3"><dfn id="zqfy3"></dfn></strong></blockquote>
          <blockquote id="zqfy3"><legend id="zqfy3"></legend></blockquote>
          打開(kāi)APP
          userphoto
          未登錄

          開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

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

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

          使用 trace_printk 打印跟蹤信息

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

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

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

          清單 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);

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

          清單 2. 對(duì)模塊 ftrace_demo 進(jìn)行跟蹤
           [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  # 重新進(jìn)行模塊 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 */

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

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

          回頁(yè)首

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

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

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

          清單 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);

          下面對(duì)其進(jìn)行跟蹤,如清單 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

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

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

           if (condition) 	 tracing_on() or tracing_off()

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

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

          回頁(yè)首

          小結(jié)

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

          參考資料

          本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
          打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
          猜你喜歡
          類似文章
          linux設(shè)備驅(qū)動(dòng)歸納總結(jié)(二):模塊的相關(guān)基礎(chǔ)概念
          [原創(chuàng)]Linux 2.6內(nèi)核的編譯步驟及模塊的動(dòng)態(tài)加載 - 內(nèi)核源碼學(xué)習(xí) - Linux論壇
          最簡(jiǎn)單的內(nèi)核模塊編程
          《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》讀書筆記(六)
          2.6內(nèi)核模塊的編寫框架和編譯方法
          Linux驅(qū)動(dòng)程序入門—Hello World - 藍(lán)博芯科
          更多類似文章 >>
          生活服務(wù)
          分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
          綁定賬號(hào)成功
          后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
          如果VIP功能使用有故障,
          可點(diǎn)擊這里聯(lián)系客服!

          聯(lián)系客服