Fixes spin_trylock()
[akaros.git] / kern / arch / x86 / kdebug.c
index 94af666..fb73151 100644 (file)
@@ -8,6 +8,7 @@
 #include <kdebug.h>
 #include <pmap.h>
 #include <process.h>
+#include <kmalloc.h>
 
 #include <ros/memlayout.h>
 
@@ -163,6 +164,7 @@ debuginfo_eip(uintptr_t addr, eipdebuginfo_t *NONNULL info)
                /* TODO: short circuiting this, til our user space apps pack stab data
                 * the kernel knows about */
                return -1;
+               #if 0
                // The user-application linker script, user/user.ld,
                // puts information about the application's stabs (equivalent
                // to __STAB_BEGIN__, __STAB_END__, __STABSTR_BEGIN__, and
@@ -181,6 +183,7 @@ debuginfo_eip(uintptr_t addr, eipdebuginfo_t *NONNULL info)
 
                // Make sure the STABS and string table memory is valid.
                // LAB 3: Your code here.
+               #endif
        }
 
        if (!stab_table_valid(stabstr, stabstr_end))
@@ -304,45 +307,62 @@ void *debug_get_fn_addr(char *fn_name)
        return retval;
 }
 
-void backtrace(void)
+void backtrace_frame(uintptr_t eip, uintptr_t ebp)
 { 
        extern char (SNT RO _start)[];
-       uint32_t *ebp, eip;
        eipdebuginfo_t debuginfo;
        char buf[256];
+       char *func_name;
        int j, i = 1;
-       ebp = (uint32_t*)read_ebp();
-       // this is part of the way back into the call() instruction's bytes
-       // eagle-eyed readers should be able to explain why this is good enough,
-       // and retaddr (just *(ebp + 1) is not)
-       eip = *(ebp + 1) - 1;
-       // jump back a frame (out of backtrace)
-       ebp = (uint32_t*)(*ebp);
-       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) {
+       while (ebp) {
+               #ifdef CONFIG_X86_64
+               func_name = get_fn_name(eip);
+               printk("#%02d [<%p>] in %s\n", i++,  eip, func_name);
+               # ifdef CONFIG_RESET_STACKS
+               if (func_name && !strncmp("__smp_idle", func_name, 10))
+                       break;
+               # endif /* CONFIG_RESET_STACKS */
+               kfree(func_name);
+               #else
                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;
                cprintf("#%02d [<%p>] in %s+%x(%p) from %s:%d\n", i++,  eip, buf, 
-                       debuginfo.eip_fn_addr - (uint32_t)_start, debuginfo.eip_fn_addr, 
-                       debuginfo.eip_file, debuginfo.eip_line);
+                       debuginfo.eip_fn_addr - (uintptr_t)_start,
+                       debuginfo.eip_fn_addr, debuginfo.eip_file, debuginfo.eip_line);
                cprintf("    ebp: %x   Args:", ebp);
                for (j = 0; j < MIN(debuginfo.eip_fn_narg, 5); j++)
-                       cprintf(" %08x", *(ebp + 2 + j));
+                       cprintf(" %08x", *(uintptr_t*)(ebp + 2 + j));
                cprintf("\n");
-               if (!ebp)
-                       break;
-               eip = *(ebp + 1) - 1;
-               ebp = (uint32_t*)(*ebp);
-               #ifdef CONFIG_RESET_STACKS
-               if (!strncmp("__smp_idle", debuginfo.eip_fn_name, 10))
+               # ifdef CONFIG_RESET_STACKS
+               if (!strncmp("__smp_idle", (char*)debuginfo.eip_fn_name, 10))
                        break;
-               #endif /* CONFIG_RESET_STACKS */
+               # endif /* CONFIG_RESET_STACKS */
+               #endif /* CONFIG_X86_64 */
+               eip = *(uintptr_t*)(ebp + sizeof(uintptr_t)) - 1;
+               ebp = *(uintptr_t*)ebp;
        }
 }
 
+void backtrace(void)
+{
+       uintptr_t ebp, eip;
+       ebp = read_bp();
+       /* retaddr is right above ebp on the stack.  we subtract an additional 1 to
+        * make sure the eip we get is actually in the function that called us.
+        * i had a couple cases early on where call was the last instruction in a
+        * function, and simply reading the retaddr would point into another
+        * function (the next one in the object) */
+       eip = *(uintptr_t*)(ebp + sizeof(uintptr_t)) - 1;
+       /* jump back a frame (out of backtrace) */
+       ebp = *(uintptr_t*)ebp;
+       printk("Stack Backtrace on Core %d:\n", core_id());
+       backtrace_frame(eip, ebp);
+}
+
 /* Assumes 32-bit header */
 void print_fpu_state(struct ancillary_state *fpu)
 {