From 8733b7318dc0d667cb890d91c320e366af4b3272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 9 Aug 2005 16:09:26 +0000 Subject: [PATCH] The stack trace in the kernel debugger is now safe against accessing invalid user memory (it got its own fault handler). IOW the stack frame is not changed in that case anymore. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13921 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/arch/x86/arch_debug.c | 34 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_debug.c b/src/system/kernel/arch/x86/arch_debug.c index 90a3d76e86..f9526c04f7 100644 --- a/src/system/kernel/arch/x86/arch_debug.c +++ b/src/system/kernel/arch/x86/arch_debug.c @@ -48,6 +48,24 @@ already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp) } +static status_t +get_next_frame(addr_t ebp, addr_t *_next, addr_t *_eip) +{ + // set fault handler, so that we can safely access user stacks + thread_get_current_thread()->fault_handler = (addr_t)&&error; + + *_eip = ((struct stack_frame *)ebp)->return_address; + *_next = (addr_t)((struct stack_frame *)ebp)->previous; + + thread_get_current_thread()->fault_handler = NULL; + return B_OK; + +error: + thread_get_current_thread()->fault_handler = NULL; + return B_BAD_ADDRESS; +} + + static int stack_trace(int argc, char **argv) { @@ -88,6 +106,7 @@ stack_trace(int argc, char **argv) kprintf("frame caller :function + offset\n"); read_ebp(ebp); + for (;;) { bool isIFrame = false; // see if the ebp matches the iframe @@ -115,16 +134,25 @@ stack_trace(int argc, char **argv) kprintf(" vector: 0x%x, error code: 0x%x\n", frame->vector, frame->error_code); ebp = frame->ebp; } else { - addr_t eip = ((struct stack_frame *)ebp)->return_address; + addr_t eip, nextEbp, diff; const char *symbol, *image; - addr_t nextEbp = (addr_t)((struct stack_frame *)ebp)->previous; addr_t baseAddress; bool exactMatch; - addr_t diff = nextEbp - ebp; + + if (get_next_frame(ebp, &nextEbp, &eip) != B_OK) { + kprintf("%08lx -- read fault\n", ebp); + break; + } if (eip == 0 || ebp == 0) break; + diff = nextEbp - ebp; + + // kernel space/user space switch + if (diff & 0x80000000) + diff = 0; + if (elf_lookup_symbol_address(eip, &baseAddress, &symbol, &image, &exactMatch) == B_OK) { if (symbol != NULL) {