星期四, 4月 14, 2011

About BUG_ON and WARN_ON

在 linux kernel 中可以常常看到 BUG_ON 與 WARN_ON 這兩個 macro.
BUG_ON 與 WARN_ON 有點像是我們平常在用的 assert, 不過作用剛好相反.
當 BUG_ON 裡的條件式為真時, 表示 kernel 有 bug, 這時會呼叫 panic 終止 kernel 運行.

我們可以在 include/asm-generic/bug.h 這裡找到這幾個宣告.
在 BUG_ON 裡可以看到如果判斷式為真時, 就呼叫 BUG 這個 macro,
繼續追蹤下去可看到 BUG 會把檔案, 函式與行號印出之後呼叫 panic() 讓 kernel 停止,
而 WARN_ON 則是把 panic() 換成 dump stack() 而已, 至於 unlikely 跟 likely 的用法請參考 Linux Device Driver 這本書, 裡有說明.
如下:

#ifndef HAVE_ARCH_BUG
#define BUG() do { \
 printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
 panic("BUG!"); \
} while (0)
#endif

#ifndef HAVE_ARCH_BUG_ON
#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
#endif

#ifndef HAVE_ARCH_WARN_ON
#define WARN_ON(condition) ({      \
 typeof(condition) __ret_warn_on = (condition);   \
 if (unlikely(__ret_warn_on)) {     \
  printk("BUG: at %s:%d %s()\n", __FILE__,  \
   __LINE__, __FUNCTION__);   \
  dump_stack();      \
 }        \
 unlikely(__ret_warn_on);     \
})
#endif

沒有留言: