linux kernel log之2. dynamic_debug


這里強烈推薦驅動開發者用這種方式輸出log。linux kernel space中有pr_debugdev_dbg來使用dynamic debug。可以看到當用戶define DEBUG后,prdebug和dev_dbg就等於printk的KERN_DEBUG級別輸出了;否則什么也不打印。

一. 開啟dynamic debug功能

要使用dynamic_debug需要在kernel的defconfig中開啟

CONFIG_DEBUG_FS=y CONFIG_DYNAMIC_DEBUG=y

用menuconfig去配置的話如下圖:

二 dynamic debug功能使用

1. 編譯好image后,需要掛載debugfs(不掛載的話將不會創建debugfs,那么/sys/kernel/debug/下是空的)。

修改etc/fstab文件,追加下面這段字符。

nodev      /sys/kernel/debug debugfs   defaults    0   0

 

2. 可以用cat /sys/kernel/debug/dynamic_debug/control | grep xxx.c來查看自己想要查看的log所在文件有沒有包含進去。

那這里可以看到該文件所有用dev_dbg()打印出的訊息。

那如果不開啟CONFIG_DYNAMIC_DEBUG,將不會產生/sys/kernel/debug/dynamic_debug目錄, 是不能進行動態打印的。

開啟dynamic debug:

echo "module cvi_mipi_rx +p" > /sys/kernel/debug/dynamic_debug/control ②echo "file cvi_vip_cif.c +p" >/sys/kernel/debug/dynamic_debug/control

這兩種方式都是開dynamic debug,第一種是對模塊開啟,第二種只對文件開啟。下面舉一個栗子:

開啟之后,可以看到dev_dbg()打印的log都會輸出。

 

反之,關閉dynamic debug:

echo "module cvi_mipi_rx -p" > /sys/kernel/debug/dynamic_debug/control ②echo "file cvi_vip_cif.c -p" >/sys/kernel/debug/dynamic_debug/control

那除了上面的兩種方式還有一種可以只開啟某個function:

echo "func _init_resource +p" > /sys/kernel/debug/dynamic_debug/control

不過一般不太推薦使用這種做法,因為很多functions都是相同名字但屬於不同modules的。

三 dev_err/dev_info/dev_warn系列函數

在Linux驅動代碼中,有大量的調試信息,那么推薦使用dev_err/dev_info/dev_warn這一系列函數族。這一系列函數族定義在include/linux/device.h.

其實這些函數族本質上和下面printk.h中的定義也是完全一致的。

#define pr_emerg(fmt, ...) \ printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) #define pr_alert(fmt, ...) \ printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) #define pr_crit(fmt, ...) \ printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) #define pr_err(fmt, ...) \ printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) #define pr_warning(fmt, ...) \ printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) #define pr_warn pr_warning
#define pr_notice(fmt, ...) \ printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) #define pr_info(fmt, ...) \ printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)

下圖是示例,可以看到err級別以下的log沒有打印,那么設置printk的控制台級別可以把對應的log輸出到console(如何設置printk console level可以看上一篇1. printk & dmesg)。

 

四 可變參數宏(##__VA_ARGS__)

##__VA_ARGS__表示可變參數宏,可以用來傳遞多個參數,如:

#define my_dbg(fmt, ...) \
do {                        \
        printf("[%s] [%d] " fmt, __func__, __LINE__, ##__VA_ARGS__);\
} while(0)

#define my_dbg(fmt...) \
do { \
  printf("[%s] [%d] ", __func__, __LINE__); \
  printf(fmt); \
} while(0)

char *name = "robin"; int age = 18; my_dbg("this is a test. name:%s, age:%d\n", name, age);

 結果如下:

那和下面這種寫法呢本質上是完全一樣的。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM