开启内核bug
经常在内核模块中看到 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
参考
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