关于BUG_ON()的一点笔记
最近在看isp1362的驱动经常看到这个BUG_ON()在网上找了些相关资料,现总结如下 。
先看代码吧:
<asm-generic/bug.h> #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
对于blackfin来说有如下定义(现在没时间学习blackfin体系,还看不懂以后有时间在看了):
<arch/blackfin/include/asm/bug.h> /* * Copyright 2004-2009 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ #ifndef _BLACKFIN_BUG_H #define _BLACKFIN_BUG_H #ifdef CONFIG_BUG #define BFIN_BUG_OPCODE 0xefcd #ifdef CONFIG_DEBUG_BUGVERBOSE #define _BUG_OR_WARN(flags) / asm volatile( / "1: .hword %0/n" / " .section __bug_table,/"a/",@progbits/n" / "2: .long 1b/n" / " .long %1/n" / " .short %2/n" / " .short %3/n" / " .org 2b + %4/n" / " .previous" / : / : "i"(BFIN_BUG_OPCODE), "i"(__FILE__), / "i"(__LINE__), "i"(flags), / "i"(sizeof(struct bug_entry))) #else #define _BUG_OR_WARN(flags) / asm volatile( / "1: .hword %0/n" / " .section __bug_table,/"a/",@progbits/n" / "2: .long 1b/n" / " .short %1/n" / " .org 2b + %2/n" / " .previous" / : / : "i"(BFIN_BUG_OPCODE), "i"(flags), / "i"(sizeof(struct bug_entry))) #endif /* CONFIG_DEBUG_BUGVERBOSE */ #define BUG() / do { / _BUG_OR_WARN(0); / for (;;); / } while (0) #define WARN_ON(condition) / ({ / int __ret_warn_on = !!(condition); / if (unlikely(__ret_warn_on)) / _BUG_OR_WARN(BUGFLAG_WARNING); / unlikely(__ret_warn_on); / }) #define HAVE_ARCH_BUG #define HAVE_ARCH_WARN_ON #endif #include <asm-generic/bug.h> #endif
作用:一些内核调用可以用来方便标记bug,提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。当被调用的时候,它们会引发oops,导致栈的回溯和错误信息的打印。为什么这些声明会导致 oops跟硬件的体系结构是相关的。大部分体系结构把BUG()和BUG_ON()定义成某种非法操作,这样自然会产生需要的oops。你可以把这些调用当作断言使用,想要断言某种情况不该发生 :
if (bad_thing)
BUG();
或者使用更好的形式:
BUG_ON(bad_thing);
可以用panic()引发更严重的错误。调用panic()不但会打印错误消息而且还会挂起整个系统。显然,你只应该在极端恶劣的情况下使用它:
if (terrible_thing)
panic("foo is %ld/n", foo);
有些时候,你只是需要在终端上打印一下栈的回溯信息来帮助你测试。此时可以使用dump_stack()。它只在终端上打印寄存器上下文和函数的跟踪线索:
if (!debug_check) {
printk(KERN_DEBUG "provide some information.../n");
dump_stack();
}