diff --git a/kernel/calls.c b/kernel/calls.c index 5ec00e35e5..5c199acca0 100644 --- a/kernel/calls.c +++ b/kernel/calls.c @@ -251,6 +251,8 @@ syscall_t syscall_table[] = { #define NUM_SYSCALLS (sizeof(syscall_table) / sizeof(syscall_table[0])) +void dump_stack(int lines); + void handle_interrupt(int interrupt) { struct cpu_state *cpu = ¤t->cpu; if (interrupt == INT_SYSCALL) { @@ -278,6 +280,7 @@ void handle_interrupt(int interrupt) { .code = mem_segv_reason(current->mem, cpu->segfault_addr), .fault.addr = cpu->segfault_addr, }; + dump_stack(8); deliver_signal(current, SIGSEGV_, info); } } else if (interrupt == INT_UNDEFINED) { @@ -289,6 +292,7 @@ void handle_interrupt(int interrupt) { printk("%02x ", b); } printk("\n"); + dump_stack(8); struct siginfo_ info = { .code = SI_KERNEL_, .fault.addr = cpu->eip, @@ -338,18 +342,26 @@ void dump_maps(void) { free(orig_data); } -void dump_stack(int lines) { - printk("stack at %x, base at %x, ip at %x\n", current->cpu.esp, current->cpu.ebp, current->cpu.eip); - for (int i = 0; i < lines*8; i++) { - dword_t stackword; - if (user_get(current->cpu.esp + (i * 4), stackword)) +void dump_mem(addr_t start, uint_t len) { + const int width = 8; + for (addr_t addr = start; addr < start + len; addr += sizeof(dword_t)) { + unsigned from_left = (addr - start) / sizeof(dword_t) % width; + if (from_left == 0) + printk("%08x: ", addr); + dword_t word; + if (user_get(addr, word)) break; - printk("%08x ", stackword); - if (i % 8 == 7) + printk("%08x ", word); + if (from_left == width - 1) printk("\n"); } } +void dump_stack(int lines) { + printk("stack at %x, base at %x, ip at %x\n", current->cpu.esp, current->cpu.ebp, current->cpu.eip); + dump_mem(current->cpu.esp, lines * sizeof(dword_t) * 8); +} + // TODO find a home for this #ifdef LOG_OVERRIDE int log_override = 0;