printk 是 kernel debug 中经常用到的方法,可以在某个代码片段中加入 printk 来 view 某些关键的变量,但是如果要调试的代码是中断处理程序,比如 timer_interrupt, smp_apic_timer_interrupt 那用 printk 的话结果就悲剧了,但是我们可以通过某种方法来设置何时 printk .此时就用到了这个 panic_on_oops 变量

  • 使用方法很简单,不过要重新 build 个 kernel <ol style="list-style-type: decimal;">
  • 修改 /kernel/panic.c 中 panic_on_oops 变量为 0
  • 在需要调试的代码段中加入 if (panic_on_oops) { instructions }
  • </ol>

Example :

diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 187e252..ac816b7 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -624,6 +624,11 @@ static inline void set_cyc2ns_scale(unsigned long cpu_khz)

 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
 {
+        if (panic_on_oops){
+                printk(KERN_INFO "=> XXXXXX");
+                ......
+        }
+
        return (cyc * cyc2ns_scale) >> NS_SCALE;
 }

diff --git a/kernel/panic.c b/kernel/panic.c
index edb779e..37cb952 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -20,7 +20,7 @@
 #include <linux/kexec.h>
 #include <linux/debug_locks.h>

-int panic_on_oops = 1;
+int panic_on_oops = 0;
 int tainted;
 static int pause_on_oops;
 static int pause_on_oops_flag;

Checking and Setting

待新 kernel build 好之后,查看以及设置当前 kernel panic_on_oops vaule

  • Checking

    cat /proc/sys/kernel/panic_on_oops

  • Setting

    • enable

      echo “1” > /proc/sys/kernel/panic_on_oops

    • disable

      echo “0” > /proc/sys/kernel/panic_on_oops