diff --git a/headers/private/kernel/arch/arm/arch_debug.h b/headers/private/kernel/arch/arm/arch_debug.h new file mode 100644 index 0000000000..dff4020e7e --- /dev/null +++ b/headers/private/kernel/arch/arm/arch_debug.h @@ -0,0 +1,16 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_ARM_DEBUG_H +#define _KERNEL_ARCH_ARM_DEBUG_H + + +#include + + +struct arch_debug_registers { +}; + + +#endif // _KERNEL_ARCH_ARM_DEBUG_H diff --git a/headers/private/kernel/arch/debug.h b/headers/private/kernel/arch/debug.h index 4da4468caf..1ef4104f9f 100644 --- a/headers/private/kernel/arch/debug.h +++ b/headers/private/kernel/arch/debug.h @@ -11,6 +11,7 @@ #include +#include #include @@ -35,7 +36,7 @@ int32 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, void* arch_debug_get_interrupt_pc(bool* _isSyscall); bool arch_debug_contains_call(struct thread *thread, const char *symbol, addr_t start, addr_t end); -void arch_debug_save_registers(int *); +void arch_debug_save_registers(struct arch_debug_registers* registers); void arch_debug_unset_current_thread(void); void arch_debug_call_with_fault_handler(cpu_ent* cpu, jmp_buf jumpBuffer, void (*function)(void*), void* parameter); diff --git a/headers/private/kernel/arch/m68k/arch_debug.h b/headers/private/kernel/arch/m68k/arch_debug.h new file mode 100644 index 0000000000..eba42e03a4 --- /dev/null +++ b/headers/private/kernel/arch/m68k/arch_debug.h @@ -0,0 +1,16 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_M68K_DEBUG_H +#define _KERNEL_ARCH_M68K_DEBUG_H + + +#include + + +struct arch_debug_registers { +}; + + +#endif // _KERNEL_ARCH_M68K_DEBUG_H diff --git a/headers/private/kernel/arch/mipsel/arch_debug.h b/headers/private/kernel/arch/mipsel/arch_debug.h new file mode 100644 index 0000000000..03edbf6a0d --- /dev/null +++ b/headers/private/kernel/arch/mipsel/arch_debug.h @@ -0,0 +1,16 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_MIPSEL_DEBUG_H +#define _KERNEL_ARCH_MIPSEL_DEBUG_H + + +#include + + +struct arch_debug_registers { +}; + + +#endif // _KERNEL_ARCH_MIPSEL_DEBUG_H diff --git a/headers/private/kernel/arch/ppc/arch_debug.h b/headers/private/kernel/arch/ppc/arch_debug.h new file mode 100644 index 0000000000..745874dce1 --- /dev/null +++ b/headers/private/kernel/arch/ppc/arch_debug.h @@ -0,0 +1,16 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_PPC_DEBUG_H +#define _KERNEL_ARCH_PPC_DEBUG_H + + +#include + + +struct arch_debug_registers { +}; + + +#endif // _KERNEL_ARCH_PPC_DEBUG_H diff --git a/headers/private/kernel/arch/x86/arch_debug.h b/headers/private/kernel/arch/x86/arch_debug.h new file mode 100644 index 0000000000..789ecc7461 --- /dev/null +++ b/headers/private/kernel/arch/x86/arch_debug.h @@ -0,0 +1,17 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_X86_DEBUG_H +#define _KERNEL_ARCH_X86_DEBUG_H + + +#include + + +struct arch_debug_registers { + uint32 ebp; +}; + + +#endif // _KERNEL_ARCH_X86_DEBUG_H diff --git a/headers/private/kernel/debug.h b/headers/private/kernel/debug.h index 7508536764..4ef6f583af 100644 --- a/headers/private/kernel/debug.h +++ b/headers/private/kernel/debug.h @@ -67,6 +67,10 @@ #define B_KDEBUG_DONT_PARSE_ARGUMENTS (0x01) #define B_KDEBUG_PIPE_FINAL_RERUN (0x02) + +struct arch_debug_registers; + + struct debugger_module_info { module_info info; @@ -92,8 +96,6 @@ struct debugger_demangle_module_info { }; -extern int dbg_register_file[B_MAX_CPU_COUNT][14]; - typedef struct debug_page_fault_info { addr_t fault_address; addr_t pc; @@ -170,6 +172,8 @@ extern status_t debug_get_next_demangled_argument(uint32* _cookie, extern struct thread* debug_set_debugged_thread(struct thread* thread); extern struct thread* debug_get_debugged_thread(); +extern struct arch_debug_registers* debug_get_debug_registers(int32 cpu); + extern status_t _user_kernel_debugger(const char *message); extern void _user_debug_output(const char *userString); diff --git a/src/system/kernel/arch/arm/arch_debug.cpp b/src/system/kernel/arch/arm/arch_debug.cpp index e78e7e4476..600130686e 100644 --- a/src/system/kernel/arch/arm/arch_debug.cpp +++ b/src/system/kernel/arch/arm/arch_debug.cpp @@ -228,7 +228,7 @@ return 0; void -arch_debug_save_registers(int *regs) +arch_debug_save_registers(struct arch_debug_registers* registers) { } diff --git a/src/system/kernel/arch/m68k/arch_debug.cpp b/src/system/kernel/arch/m68k/arch_debug.cpp index da3d670a73..0d9dd6b292 100644 --- a/src/system/kernel/arch/m68k/arch_debug.cpp +++ b/src/system/kernel/arch/m68k/arch_debug.cpp @@ -248,7 +248,7 @@ return 0; void -arch_debug_save_registers(int *regs) +arch_debug_save_registers(struct arch_debug_registers* registers) { } diff --git a/src/system/kernel/arch/mipsel/arch_debug.cpp b/src/system/kernel/arch/mipsel/arch_debug.cpp index ab2dbb27ec..384ce7932f 100644 --- a/src/system/kernel/arch/mipsel/arch_debug.cpp +++ b/src/system/kernel/arch/mipsel/arch_debug.cpp @@ -35,7 +35,7 @@ extern struct iframe_stack gBootFrameStack; void -arch_debug_save_registers(int* regs) +arch_debug_save_registers(struct arch_debug_registers* registers) { #warning IMPLEMENT arch_debug_save_registers } diff --git a/src/system/kernel/arch/ppc/arch_debug.cpp b/src/system/kernel/arch/ppc/arch_debug.cpp index 4a9decbab4..9acbf22d7e 100644 --- a/src/system/kernel/arch/ppc/arch_debug.cpp +++ b/src/system/kernel/arch/ppc/arch_debug.cpp @@ -254,7 +254,7 @@ return 0; void -arch_debug_save_registers(int *regs) +arch_debug_save_registers(struct arch_debug_registers* registers) { } diff --git a/src/system/kernel/arch/x86/arch_debug.cpp b/src/system/kernel/arch/x86/arch_debug.cpp index 7e69ccf7d6..7f2568be42 100644 --- a/src/system/kernel/arch/x86/arch_debug.cpp +++ b/src/system/kernel/arch/x86/arch_debug.cpp @@ -357,8 +357,19 @@ setup_for_thread(char *arg, struct thread **_thread, uint32 *_ebp, write_cr3(newPageDirectory); } - // read %ebp from the thread's stack stored by a pushad - *_ebp = thread->arch_info.current_stack.esp[2]; + if (thread->state == B_THREAD_RUNNING) { + // The thread is currently running on another CPU. + if (thread->cpu == NULL) + return false; + arch_debug_registers* registers = debug_get_debug_registers( + thread->cpu->cpu_num); + if (registers == NULL) + return false; + *_ebp = registers->ebp; + } else { + // read %ebp from the thread's stack stored by a pushad + *_ebp = thread->arch_info.current_stack.esp[2]; + } } else thread = NULL; } @@ -896,6 +907,15 @@ cmd_in_context(int argc, char** argv) // #pragma mark - +void +arch_debug_save_registers(struct arch_debug_registers* registers) +{ + // get the caller's frame pointer + stack_frame* frame = (stack_frame*)x86_read_ebp(); + registers->ebp = (addr_t)frame->previous; +} + + void arch_debug_stack_trace(void) { @@ -910,8 +930,21 @@ arch_debug_contains_call(struct thread *thread, const char *symbol, addr_t ebp; if (thread == thread_get_current_thread()) ebp = x86_read_ebp(); - else - ebp = thread->arch_info.current_stack.esp[2]; + else { + if (thread->state == B_THREAD_RUNNING) { + // The thread is currently running on another CPU. + if (thread->cpu == NULL) + return false; + arch_debug_registers* registers = debug_get_debug_registers( + thread->cpu->cpu_num); + if (registers == NULL) + return false; + ebp = registers->ebp; + } else { + // thread not running + ebp = thread->arch_info.current_stack.esp[2]; + } + } for (;;) { if (!is_kernel_stack_address(thread, ebp)) diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/arch_x86.S index 10ffba1d08..36255dfc76 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/arch_x86.S @@ -194,46 +194,6 @@ done: FUNCTION_END(reboot) -FUNCTION(arch_debug_save_registers): - pushl %esi - pushl %eax - movl 12(%esp), %esi - - movl %eax, 0(%esi) - movl %ebx, 4(%esi) - movl %ecx, 8(%esi) - movl %edx, 12(%esi) - - lea 16(%esp), %eax - movl %eax, 16(%esi) // caller's %esp - movl %ebp, 20(%esi) - - movl 4(%esp), %eax - movl %eax, 24(%esi) // caller's %esi - movl %edi, 28(%esi) - - movl 8(%esp), %eax - movl %eax, 32(%esi) // caller's %ebp - - pushfl - popl %eax - movl %eax, 36(%esi) - - xor %eax, %eax - movw %cs, %ax - movl %eax, 40(%esi) - movw %ss, %ax - movl %eax, 44(%esi) - movw %ds, %ax - movl %eax, 48(%esi) - movw %es, %ax - movl %eax, 52(%esi) - - popl %eax - popl %esi - ret -FUNCTION_END(arch_debug_save_registers) - /* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */ FUNCTION(arch_cpu_user_memcpy): pushl %esi diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index 3a309f63f9..b59a7ba889 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -80,9 +80,7 @@ void call_modules_hook(bool enter); static void syslog_write(const char* text, int32 length, bool notify); - -int dbg_register_file[B_MAX_CPU_COUNT][14]; - /* XXXmpetit -- must be made generic */ +static arch_debug_registers sDebugRegisters[B_MAX_CPU_COUNT]; static debug_page_fault_info sPageFaultInfo; @@ -939,7 +937,7 @@ enter_kernel_debugger(int32 cpu) smp_intercpu_int_handler(cpu); } - arch_debug_save_registers(&dbg_register_file[cpu][0]); + arch_debug_save_registers(&sDebugRegisters[cpu]); sPreviousDprintfState = set_dprintf_enabled(true); if (!gKernelStartup && sDebuggerOnCPU != cpu && smp_get_num_cpus() > 1) { @@ -1692,6 +1690,8 @@ debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver) if (sCPUTrapped[cpu]) return; + arch_debug_save_registers(&sDebugRegisters[cpu]); + sCPUTrapped[cpu] = true; while (sInDebugger != 0) { @@ -1992,6 +1992,16 @@ debug_get_next_demangled_argument(uint32* _cookie, const char* symbol, } +struct arch_debug_registers* +debug_get_debug_registers(int32 cpu) +{ + if (cpu < 0 || cpu > smp_get_num_cpus()) + return NULL; + + return &sDebugRegisters[cpu]; +} + + struct thread* debug_set_debugged_thread(struct thread* thread) { diff --git a/src/system/kernel/debug/gdb.cpp b/src/system/kernel/debug/gdb.cpp index 34cf39dcff..c2084cb9b2 100644 --- a/src/system/kernel/debug/gdb.cpp +++ b/src/system/kernel/debug/gdb.cpp @@ -228,6 +228,7 @@ gdb_parse_command(void) case 'g': { +#if 0 int cpu; // command 'g' is used for reading the register @@ -247,6 +248,10 @@ gdb_parse_command(void) // dump in *big endian* format. cpu = smp_get_current_cpu(); gdb_regreply(dbg_register_file[cpu], 14); +#else + (void)gdb_regreply; + gdb_reply("E01"); +#endif break; }