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)

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

 结果如下:

那和下面这种写法呢本质上是完全一样的。

 

原文地址:https://www.cnblogs.com/fuzidage/p/14785734.html