1. 程式人生 > >[轉]如何開啟pr_debug除錯資訊

[轉]如何開啟pr_debug除錯資訊

轉自:http://blog.csdn.net/helloanthea/article/details/25330809

如何開啟pr_debug除錯資訊,先不要著急,我們先靜下心來分析一下這個函式的原始碼。

以DMA的除錯為例,先來看看一個pr_debug函式呼叫。

pr_debug("%s: %s (%s)\n", 

          __func__, 

          chan ? "success" : "fail", 

          chan ? dma_chan_name(chan) : NULL);

include/linux/printk.h裡找到pr_debug的定義,這裡暗藏了玄機。

/* If you are writing a driver, please use dev_dbg instead */ 

#if defined(CONFIG_DYNAMIC_DEBUG) 

/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */ 

#define pr_debug(fmt, ...) \ 

        dynamic_pr_debug(fmt, ##__VA_ARGS__) 

#elif defined(DEBUG) 

#define pr_debug(fmt, ...) \ 

        printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 

#else 

#define pr_debug(fmt, ...) \  

        no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 

#endif 

原來,三個巨集作為判斷條件決定了pr_debug到底採用哪種用法:

第一種用法,如果定義了CONFIG_DYNAMIC_DEBUG,就使用動態debug機制dynamic_pr_debug();

第二種用法,如果定義了DEBUG,就使用printk(KERN_DEBUG...);

第三種用法,預設情況下,不列印。

第三種不列印肯定不是我們想要的,那麼要想讓kernel乖乖的列印除錯資訊,就只有前面兩條路可選了:要麼動態debug,要麼定義DEBUG巨集。

先說一下如何定義DEBUG巨集:

其實在kernel中很多driver已經定義好了這樣的DEBUG選項,前人栽樹,後人乘涼,我們可以先看看有沒有現成的。例如,我們經常可以看到這樣的配置選項和巨集定義:

(1) DMA Engine debugging(CONFIG_DMADEVICES_DEBUG)

(2) Power Management Debug Support(CONFIG_PM_DEBUG)

(3) Enable debug for the B2C2 FlexCopdrivers(CONFIG_PCI_DEBUG)

以DMA為例,在drivers/dma/Makefile中定義了編譯選項

ccflags-$(CONFIG_DMADEVICES_DEBUG)  := -DDEBUG
其作用相當於在drivers/dma/所有子檔案定義了巨集#define DEBUG

小夥伴們趕緊把CONFIG_DEBUG選項選上吧,然後重新編譯kernel。先別急,這樣還不夠,預設的console級別是7(在kernel/printk/printk.c中定義了#define DEFAULT_CONSOLE_LOGLEVEL7)只有那些級別“小於7”的除錯資訊才能打印出來,而printk(KERN_DEBUG...)的級別是7,那就還需要提高console列印級別。如果要檢視dma初始化的debug資訊,那就直接改程式碼,#defineDEFAULT_CONSOLE_LOGLEVEL 8。如果是runtime,可以直接通過printk的sys介面調整列印級別 

$cat /proc/sys/kernel/printk

7      4       1       7
$echo 8 > /proc/sys/kernel/printk

$cat /proc/sys/kernel/printk
8      4       1       7

ok,大功告成!

如果一些driver沒有現成的巨集可用,那麼你可以在你想debug的原始檔中直接定義DEBUG巨集,例如你想檢視driver/video/fsl-diu-fb.c的除錯資訊,直接在標頭檔案引用後新增巨集定義#define DEBUG(巨集的作用範圍相信我就不用多說了吧,就是從巨集定義開始到原始檔的末尾結束),就能如願以償了。開發人員也可以自己仿照上述方法進行定義。

下面再簡單說一下kernel的動態除錯

開啟Enable dynamic printk() support(DYNAMIC_DEBUG),那麼所有的pr_debug()/dev_debug() 之類的函式在runtime就可以動態地使用了。kernel動態除錯提供一個debugfs介面:<debugfs>/dynamic_debug/control 

這個檔案可以用來獲取已完成的除錯資訊列表,例如你要顯示檔案'svcsock.c'的1603行內容,你可以這樣做:

nullarbor:~ # echo 'file svcsock.c line 1603 +p' >

        <debugfs>/dynamic_debug/control  

// 提供檔案svcsock.c所有資訊 

nullarbor:~ # echo -n 'file svcsock.c +p' >

        <debugfs>/dynamic_debug/control 

如果你想執行多個命令,你需要為每個加入“echo”分割,像這樣:

nullarbor:~ # echo 'file svcsock.c line 1603 +p' >/proc/dprintk ;\

> echo 'file svcsock.c line 1563 +p' >/proc/dprintk

或者甚至是這樣: 

nullarbor:~ # (

> echo 'file svcsock.c line 1603 +p' ;\

> echo 'file svcsock.c line 1563 +p' ;\

> ) > /proc/dprintk 

file可以替換成module,format等匹配方式,具體用法請參考Documentation/dynamic-debug-howto.txt

好了,enjoy你的debug之旅吧!