x86: Better emergency codes for core 0
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 30 Aug 2013 18:02:05 +0000 (11:02 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 30 Aug 2013 18:06:28 +0000 (11:06 -0700)
Shift-G still works, though I suggest weaning yourself of that.  Ctrl-G
does the same thing (enters the monitor when the core is able to).  This
is the preferred way to enter the monitor.

Ctrl-Q also enters the monitor, but does so directly from IRQ context.
This can be dangerous, but is better than nothing.

Ctrl-B dumps a backtrace and trapframe of the core.  You could do this
manually after a Ctrl-Q, too.

The core that runs the backtrace or monitor is whatever core received
the IRQ.  This is almost always core 0.  Debugging remote cores can be
done from the monitor on core 0.

These codes require interrupts to be enabled.  I don't have a way to
send nmis to core 0 yet, other than from the monitor on another core.

kern/arch/x86/init.c
kern/arch/x86/trap.c
kern/src/manager.c

index fec4093..42db860 100644 (file)
 #include <arch/perfmon.h>
 #include <arch/init.h>
 #include <console.h>
+#include <monitor.h>
 
 struct ancillary_state x86_default_fpu;
 
+#define capchar2ctl(x) ((x) - '@')
+
 /* irq handler for the console (kb, serial, etc) */
 static void irq_console(struct hw_trapframe *hw_tf, void *data)
 {
@@ -24,6 +27,24 @@ static void irq_console(struct hw_trapframe *hw_tf, void *data)
        assert(cdev);
        if (cons_get_char(cdev, &c))
                return;
+       /* Control code intercepts */
+       switch (c) {
+               case capchar2ctl('G'):
+                       /* traditional 'shift-g', will put you in the monitor gracefully */
+                       send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
+                       return;
+               case capchar2ctl('Q'):
+                       /* force you into the monitor.  you might deadlock. */
+                       printk("\nForcing entry to the monitor\n");
+                       monitor(hw_tf);
+                       return;
+               case capchar2ctl('B'):
+                       /* backtrace / debugging for the core receiving the irq */
+                       printk("\nForced trapframe and backtrace for core %d\n", core_id());
+                       print_trapframe(hw_tf);
+                       backtrace_kframe(hw_tf);
+                       return;
+       }
        /* Do our work in an RKM, instead of interrupt context.  Note the RKM will
         * cast 'c' to a char. */
        if (c == 'G')
index 6a9ddc0..bbc80c9 100644 (file)
@@ -233,8 +233,10 @@ static void trap_dispatch(struct hw_trapframe *hw_tf)
                        pcpui->__lock_depth_disabled++;
                        /* This is a bit hacky, but we don't have a decent API yet */
                        extern bool mon_verbose_trace;
-                       if (mon_verbose_trace)
+                       if (mon_verbose_trace) {
                                print_trapframe(hw_tf);
+                               backtrace_kframe(hw_tf);
+                       }
                        char *fn_name = get_fn_name(x86_get_ip_hw(hw_tf));
                        printk("Core %d is at %p (%s)\n", core_id(), x86_get_ip_hw(hw_tf),
                               fn_name);
index 5cffab2..05393cd 100644 (file)
@@ -113,7 +113,14 @@ void manager_brho(void)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
 
        if (first) {    
-               printk("*** Hit shift-g to get into the monitor. ***\n");
+               printk("*** IRQs must be enabled for input emergency codes ***\n");
+               #ifdef CONFIG_X86
+               printk("*** Hit ctrl-g or shift-g to enter the monitor. ***\n");
+               printk("*** Hit ctrl-q to force-enter the monitor. ***\n");
+               printk("*** Hit ctrl-b for a backtrace of core 0 ***\n");
+               #else
+               printk("*** Hit shift-g to enter the monitor. ***\n");
+               #endif
                first = FALSE;
        }
        /* just idle, and deal with things via interrupts.  or via face. */