printk
#define KERN_EMERG "<0>" /* system is unusable 最高级别,一般只用来打印崩溃信息*/
#define KERN_ALERT "<1>" /* action must be taken immediately 需要立即处理的信息*/
#define KERN_CRIT "<2>" /* critical conditions 关键信息:严重的硬件和软件错误 */
#define KERN_ERR "<3>" /* error conditions 用来显示硬件错误 */
#define KERN_WARNING "<4>" /* warning conditions 显示不会造成严重错误的警告信息 */
#define KERN_NOTICE "<5>" /* normal but significant condition 显示需要引起注意的信息*/
#define KERN_INFO "<6>" /* informational 显示一般信息,例如驱动所发现的硬件列表 */
#define KERN_DEBUG "<7>" /* debug-level messages 用来显示调试信息 */
//举例,KERN_NOTICE 是这条打印的优先级
printk(KERN_NOTICE "%s", linux_banner);
(2)优先级总共分为0-7这8个优先级,数字越低优先级越高,在使用printk()函数时通过优先级的宏定义指定。
(3)当优先级确定时,可以通过修改控制台输出的优先级来决定是否输出某条打印;
(4)使用printk()时也可以不指定优先级,这样的printk()会有一个默认的优先级,一般是KERN_WARNING。
BUG()和BUG_ON()
类似于Assert()函数
#ifndef HAVE_ARCH_BUG
#define BUG() do { \
printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
panic("BUG!"); \
} while (0)
#endif
#ifndef HAVE_ARCH_BUG_ON
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
#endif
当调用BUG()时,内核通过panic()引发OOPS,导致函数调用栈的回溯和打印错误消息,可以把这两个调用当做断言使用,如BUG_ON(bad_thing);
dump_stack()
if(!debug_check)
{
printk(KERN_DEBUG "provide some information···\n");
dump_strack();
}
调用dump_stack()函数会在终端打印栈的回溯消息,有助于调试。
dmsg
看内核log的命令
动态调试
首先需要配置宏命令CONFIG_DYNAMIC_DEBUG=y,通过pr_debug()/dev_debug()打印信息可以动态显示或不显示
KDBG
gdb
(1)使用gdb调试内核就是把内核当做一个应用程序,首先要掌握gdb命令、了解目标平台的汇编代码,具备对源代码和优化后的汇编代码进行匹配的能力;
(2)为了让gdb使用内核的符号信息,必须打开CONFIG_DEBUG_INFO编译选项;
(3)内核需要未压缩的内核镜像文件,还需要在命令行提供core文件的命令。例如:gdb /usr/src/linux/vmlinux /proc/kcore