经常在内核模块中看到 pr_debug() 那么如何使用它呢?如何将调试信息发送到控制台呢?

pr_debug() 在 include/linux/printk.h 中被定义。

/* 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

dev_dbg 也有着类似的定义。

#if defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, format, ...)		     \
do {						     \
	dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
} while (0)
#elif defined(DEBUG)
#define dev_dbg(dev, format, arg...)		\
	dev_printk(KERN_DEBUG, dev, format, ##arg)
#else
#define dev_dbg(dev, format, arg...)				\
({								\
	if (0)							\
		dev_printk(KERN_DEBUG, dev, format, ##arg);	\
})
#endif

首先要在Makefile文件或者在其模块中直接定义 DEBUG 从而打开 printk()
但是这样也不是完全行的。因为打印调试信息还是有级别的!
printk()参数中的宏代表了打印的级别。 这些宏被定义在 <linux/device.h> 中。 基本也可以看出数字越代表的级别就越高。


#define KERN_EMERG    KERN_SOH "0"      /* system is unusable */
#define KERN_ALERT    KERN_SOH "1"      /* action must be taken immediately */
#define KERN_CRIT    KERN_SOH "2"       / * critical conditions */
#define KERN_ERR    KERN_SOH "3"        /* error conditions */
#define KERN_WARNING    KERN_SOH "4"    /* warning conditions */
#define KERN_NOTICE    KERN_SOH "5"     /* normal but significant condition */
#define KERN_INFO    KERN_SOH "6"       /* informational */
#define KERN_DEBUG    KERN_SOH "7"      /* debug-level messages */

这些级别在哪里使用呢?也就是哪里判断这些级别来打印呢?当然你也可以直接修改 kernel/printk/printk.c 改变默认打印的级别。 还有就是改变 /proc下的printk 。

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

这样就可以在控制台上看到调试信息啦~

/proc/sys/kernel/printk 下 4 个数字的含义。

这四个值是在kernel/printk.c中被定义的:

int console_printk[4] = {

                DEFAULT_CONSOLE_LOGLEVEL,       /* console_loglevel */

                DEFAULT_MESSAGE_LOGLEVEL,       /* default_message_loglevel */

                MINIMUM_CONSOLE_LOGLEVEL,     /* minimum_console_loglevel */

                DEFAULT_CONSOLE_LOGLEVEL,       /* default_console_loglevel */

};

(1)第一个参数 7表示小于7优先级消息才会被输出到控制台。

(2)第二个参数4 表示默认的printk消息优先级别,即printk(“hell world”);优先级为4, 由于4<7,故可以被打印到控制台。

(3)第三个参数1 表示可接收的最高优先级,当printk disable控制台输出时,设置第一个参数为1,但是,从内核等级来看,还有优先级0,这个是printk最高级优先级,一般用于内核严重消息打印。比如内存错误或者 watchdog reset.也可以设置第一个和第三个参数为0

(4)第四个参数7 默认控制台优先级,即第一个参数的默认优先级。

还有一种方法看翻译dynamic-debug-howto.txt

slbt

参考

https://blog.csdn.net/u012385733/article/details/76088274

https://www.mjmwired.net/kernel/Documentation/dynamic-debug-howto.txt

https://blog.csdn.net/helloanthea/article/details/25330809