Better debugging for user faults
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 23 Dec 2014 18:34:57 +0000 (10:34 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 31 Dec 2014 18:03:09 +0000 (13:03 -0500)
Whenever userspace has an unhandled fault, we print out more
information, including the 'physical' location of the faulting
instruction pointer (meaning the relative location in a file-backed
VMR).

For example:

Unhandled SCP trap
HW TRAP frame at 0xffffffffc58777b8 on core 0
  rax  0x00007f7fffbfdc38
  rbx  0x0000400000353dc0
  rcx  0x00000000fbad240c
  rdx  0x0000000000000063
  rbp  0x0000400000121348
  rsi  0x0000000000000000
  rdi  0x0000400000121348
  r8   0x0000000000000000
  r9   0x0000000000000000
  r10  0x0000000000320888
  r11  0x0000400000075990
  r12  0x0000000000000000
  r13  0x0000000000000000
  r14  0x0000000000000000
  r15  0x0000000000000000
  trap 0x0000000e Page Fault
  gsbs 0x0000000000000000
  fsbs 0x0000400000354fc0
  err  0x--------00000004
  rip  0x00004000000e0105
  cs   0x------------0023
  flag 0x0000000000010202
  rsp  0x00007f7fffbfdc20
  ss   0x------------001b
err 0x4, aux 0x00000000000000c7
Addr 0x00004000000e0105 is in libc-2.19.so at offset 0x00000000000df105

kern/include/kdebug.h
kern/src/kdebug.c
kern/src/trap.c

index 40d401f..49d2021 100644 (file)
@@ -41,4 +41,7 @@ void set_printx(int mode);
 #include <oprofile.h>
 #define TRACEME() oprofile_add_backtrace(read_pc(), read_bp())
 
+void debug_addr_proc(struct proc *p, unsigned long addr);
+void debug_addr_pid(int pid, unsigned long addr);
+
 #endif /* ROS_KERN_KDEBUG_H */
index 3946e81..87f8132 100644 (file)
@@ -146,3 +146,38 @@ void set_printx(int mode)
                        break;
        }
 }
+
+void debug_addr_proc(struct proc *p, unsigned long addr)
+{
+       struct vm_region *vmr;
+       spin_lock(&p->vmr_lock);
+       TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
+               if ((vmr->vm_base <= addr) && (addr < vmr->vm_end))
+                       break;
+       }
+       if (!vmr) {
+               spin_unlock(&p->vmr_lock);
+               printk("Addr %p has no VMR\n", addr);
+               return;
+       }
+       if (!vmr->vm_file) {
+               spin_unlock(&p->vmr_lock);
+               printk("Addr %p's VMR has no file\n", addr);
+               return;
+       }
+       printk("Addr %p is in %s at offset %p\n", addr, file_name(vmr->vm_file),
+              addr - vmr->vm_base + vmr->vm_foff);
+       spin_unlock(&p->vmr_lock);
+}
+
+void debug_addr_pid(int pid, unsigned long addr)
+{
+       struct proc *p;
+       p = pid2proc(pid);
+       if (!p) {
+               printk("No such proc for pid %d\n", pid);
+               return;
+       }
+       debug_addr_proc(p, addr);
+       proc_decref(p);
+}
index ead4965..4fac486 100644 (file)
@@ -48,6 +48,8 @@ void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
 error_out:
        print_trapframe(hw_tf);
        enable_irq();
+       printk("err 0x%x, aux %p\n", err, aux);
+       debug_addr_proc(p, get_hwtf_pc(hw_tf));
        proc_destroy(p);
 }