Linux内核调试方法总结之调试宏

本文介绍的内核调试宏属于静态调试方法,通过调试宏主动触发oops从而打印出函数调用栈信息。

 

1) BUG_ON 查看bug处堆栈内容,主动制造oops

Linux中BUG_ON,WARN_ON用于调试,比如

#define BUG_ON(condition) do { /

         if (unlikely((condition)!=0)) /

                 BUG(); /

 } while(0)

如果觉得该condition下是一个BUG,可以添加此调试信息,查看对应堆栈内容

具体的BUG_ON最终调用__bug

__bug

{

*(int*)0=0;

}

从而地址非法访问,例如在你的驱动中调用BUG_ON(1),dmesg会出现下面类似信息:

[   19.360000] Unable to handle kernel NULL pointer dereference at virtual address 00000000

[   19.360000] pgd = c0004000

[   19.360000] [00000000] *pgd=00000000

 

函数的调用流程为

fault.c

__do_kernel_fault--------[   19.360000] Unable to handle kernel NULL pointer dereference at virtual address 00000000

traps.c

die--->__die--->__show_regs   /   dump_mem

 

2) WARN_ON 调用dump_stack打印堆栈信息,不会oops

#define WARN_ON(condition) do{/

         if(unlikely((condition) != 0)) {/

                   printk(“Badness in %s at %s:%d\n”, __FUNCTION__, __FILE__, __LINE__);/

                   dump_stack();/

}

}while(0)

 

3)     BUILD_BUG_ON 编译调试宏

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

BUILD_BUG_ON宏中的condition如果为真就会报错。假设条件为真,则BUILD_BUG_ON变化为:(void) sizeof (char[-1]),这种语法是在难理解,因为char[-1]本来就是非法的。结果导致编译错误。

例子:

#define condition 0

static int __init main_init(void)

{

         printk("in %s function\n", __func__);

 

         BUILD_BUG_ON(condition);/*if the macro "confition" is not zero, the program can not be compiled to success. so the BUILD_BUG_ON used for the build of program*/

 

         WARN_ON(!condition);/*if the macro "confition" is not zero, there will dump the satck information for this program. so the WARN_ON used for debugof program*/

 

         BUG_ON(condition);  /*if the macro "confition" is not zero, The kernel will occur an Oops errro "Unable to handle kernel NULL pointer dereference at virtual address 00000000". so the BUG_ON used for ending the bug program*/

        

         return 0;

}

posted on 2016-04-23 13:50  者旨於陽  阅读(2036)  评论(0编辑  收藏  举报

导航