Debug tools use the symbol table
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 17 Jul 2013 18:13:11 +0000 (11:13 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 17 Jul 2013 18:13:11 +0000 (11:13 -0700)
Including kfunc (now available for riscv!), x86_64 backtrace, and spinlock
debug.

This also allows us to clean up the headers a bit (remove eipdebuginfo, make
spinlock debug arch independent).

kern/arch/riscv/atomic.h
kern/arch/riscv/kdebug.c
kern/arch/x86/cpuinfo.c
kern/arch/x86/kdebug.c
kern/arch/x86/kdebug.h
kern/include/atomic.h
kern/include/kdebug.h
kern/src/atomic.c
kern/src/monitor.c

index b3cbfa9..99a4e58 100644 (file)
@@ -155,8 +155,4 @@ static inline void __spinlock_init(spinlock_t *lock)
        lock->rlock = 0;
 }
 
-static inline void spinlock_debug(spinlock_t* lock)
-{
-}
-
 #endif /* ROS_KERN_ARCH_ATOMIC_H */
index 4869e5d..b517e18 100644 (file)
 
 #include <ros/memlayout.h>
 
-int debuginfo_eip(uintptr_t eip, struct eipdebuginfo *info)
-{
-       // DWARF-2 works for RISC-V, so in principle this is implementable.
-       
-       static bool once = TRUE;
-       if (once) {
-               warn("Not implemented for RISC-V");
-               once = FALSE;
-       }
-       return 0;
-}
-
 void backtrace(void)
 {
        void **fp;
index d3b7884..a653fd2 100644 (file)
@@ -192,25 +192,3 @@ void show_mapping(uintptr_t start, size_t size)
                }
        }
 }
-
-/* Like backtrace, this is probably not the best place for this. */
-void spinlock_debug(spinlock_t *lock)
-{
-#ifdef CONFIG_SPINLOCK_DEBUG
-       eipdebuginfo_t debuginfo;
-       char buf[256];
-       uint32_t eip = (uint32_t)lock->call_site;
-
-       if (!eip) {
-               printk("Lock %p: never locked\n", lock);
-               return;
-       }
-       debuginfo_eip(eip, &debuginfo);
-       memset(buf, 0, 256);
-       strncpy(buf, debuginfo.eip_fn_name, MIN(debuginfo.eip_fn_namelen, 256));
-       buf[MIN(debuginfo.eip_fn_namelen, 255)] = 0;
-       printk("Lock %p: last locked at [<%p>] in %s(%p) on core %d\n", lock, eip, buf,
-              debuginfo.eip_fn_addr, lock->calling_core);
-#endif
-}
-
index cb11235..659b62b 100644 (file)
@@ -8,6 +8,7 @@
 #include <kdebug.h>
 #include <pmap.h>
 #include <process.h>
+#include <kmalloc.h>
 
 #include <ros/memlayout.h>
 
@@ -312,6 +313,7 @@ void backtrace(void)
        unsigned long *ebp, eip;
        eipdebuginfo_t debuginfo;
        char buf[256];
+       char *func_name;
        int j, i = 1;
        ebp = (unsigned long*)read_bp();
        // this is part of the way back into the call() instruction's bytes
@@ -323,6 +325,11 @@ void backtrace(void)
        printk("Stack Backtrace on Core %d:\n", core_id());
        // on each iteration, ebp holds the stack frame and eip an addr in that func
        while (1) {
+               #ifdef CONFIG_X86_64
+               func_name = get_fn_name(eip);
+               printk("#%02d [<%p>] in %s\n", i++,  eip, func_name);
+               kfree(func_name);
+               #else
                debuginfo_eip(eip, &debuginfo);
                memset(buf, 0, 256);
                strncpy(buf, debuginfo.eip_fn_name, MIN(debuginfo.eip_fn_namelen, 256));
@@ -334,12 +341,14 @@ void backtrace(void)
                for (j = 0; j < MIN(debuginfo.eip_fn_narg, 5); j++)
                        cprintf(" %08x", *(ebp + 2 + j));
                cprintf("\n");
+               func_name = (char*)debuginfo.eip_fn_name;
+               #endif
                if (!ebp)
                        break;
                eip = *(ebp + 1) - 1;
                ebp = (unsigned long*)(*ebp);
                #ifdef CONFIG_RESET_STACKS
-               if (!strncmp("__smp_idle", debuginfo.eip_fn_name, 10))
+               if (!strncmp("__smp_idle", func_name, 10))
                        break;
                #endif /* CONFIG_RESET_STACKS */
        }
index 025a3b6..2a733c1 100644 (file)
 
 #include <stdio.h>
 
+// Debug information about a particular instruction pointer
+typedef struct eipdebuginfo {
+       const char *eip_file;           // Source code filename for EIP
+       int eip_line;                           // Source code linenumber for EIP
+
+       const char *eip_fn_name;        // Name of function containing EIP
+                                                               //  - Note: not null terminated!
+       int eip_fn_namelen;                     // Length of function name
+       uintptr_t eip_fn_addr;          // Address of start of function
+       int eip_fn_narg;                        // Number of function arguments
+} eipdebuginfo_t;
+
+int debuginfo_eip(uintptr_t eip, eipdebuginfo_t *NONNULL info);
+void *debug_get_fn_addr(char *fn_name);
+
 /* Returns a PC/EIP in the function that called us, preferably near the call
  * site.  Returns 0 when we can't jump back any farther. */
 static inline uintptr_t get_caller_pc(void)
index b4da7b7..2c6919b 100644 (file)
@@ -61,7 +61,6 @@ extern inline void __spinlock_init(spinlock_t *lock);
 extern inline bool spin_locked(spinlock_t *lock);
 extern inline void __spin_lock(spinlock_t *lock);
 extern inline void __spin_unlock(spinlock_t *lock);
-extern inline void spinlock_debug(spinlock_t *lock);
 
 /* So we can inline a __spin_lock if we want.  Even though we don't need this
  * if we're debugging, its helpful to keep the include at the same place for
@@ -72,6 +71,7 @@ extern inline void spinlock_debug(spinlock_t *lock);
 /* Arch indep, in k/s/atomic.c */
 void spin_lock(spinlock_t *lock);
 void spin_unlock(spinlock_t *lock);
+void spinlock_debug(spinlock_t *lock);
 
 #else
 /* Just inline the arch-specific __ versions */
@@ -85,6 +85,10 @@ static inline void spin_unlock(spinlock_t *lock)
        __spin_unlock(lock);
 }
 
+static inline void spinlock_debug(spinlock_t *lock)
+{
+}
+
 #endif /* CONFIG_SPINLOCK_DEBUG */
 
 /* Inlines, defined below */
index 478e2f8..058a42a 100644 (file)
@@ -9,20 +9,6 @@ struct symtab_entry {
        uintptr_t addr;
 };
 
-// Debug information about a particular instruction pointer
-typedef struct eipdebuginfo {
-       const char *eip_file;           // Source code filename for EIP
-       int eip_line;                           // Source code linenumber for EIP
-
-       const char *eip_fn_name;        // Name of function containing EIP
-                                                               //  - Note: not null terminated!
-       int eip_fn_namelen;                     // Length of function name
-       uintptr_t eip_fn_addr;          // Address of start of function
-       int eip_fn_narg;                        // Number of function arguments
-} eipdebuginfo_t;
-
-int debuginfo_eip(uintptr_t eip, eipdebuginfo_t *NONNULL info);
-void *debug_get_fn_addr(char *fn_name);
 void backtrace(void);
 
 /* Arch dependent, listed here for ease-of-use */
index c529b42..099605c 100644 (file)
@@ -12,6 +12,8 @@
 #include <assert.h>
 #include <hashtable.h>
 #include <smp.h>
+#include <kmalloc.h>
+#include <kdebug.h>
 
 static void increase_lock_depth(uint32_t coreid)
 {
@@ -62,6 +64,22 @@ void spin_unlock(spinlock_t *lock)
        /* Memory barriers are handled by the particular arches */
        __spin_unlock(lock);
 }
+
+void spinlock_debug(spinlock_t *lock)
+{
+       uintptr_t pc = lock->call_site;
+       char *func_name;
+
+       if (!pc) {
+               printk("Lock %p: never locked\n", lock);
+               return;
+       }
+       func_name = get_fn_name(pc);
+       printk("Lock %p: last locked at [<%p>] in %s on core %d\n", lock, pc,
+              func_name, lock->calling_core);
+       kfree(func_name);
+}
+
 #endif /* CONFIG_SPINLOCK_DEBUG */
 
 /* Inits a hashlock. */
index 254e514..bd2f8ea 100644 (file)
@@ -375,11 +375,6 @@ int mon_exit(int argc, char **argv, struct hw_trapframe *hw_tf)
 
 int mon_kfunc(int argc, char **argv, struct hw_trapframe *hw_tf)
 {
-       #ifndef CONFIG_X86
-       printk("Only supported on x86 for now.  =(\n");
-       return -1;
-       #endif
-
        void (*func)(void *arg, ...);
 
        if (argc < 2) {
@@ -387,7 +382,7 @@ int mon_kfunc(int argc, char **argv, struct hw_trapframe *hw_tf)
                printk("Arguments must be in hex.  Can take 6 args.\n");
                return 1;
        }
-       func = debug_get_fn_addr(argv[1]);
+       func = (void*)get_symbol_addr(argv[1]);
        if (!func) {
                printk("Function not found.\n");
                return 1;