* Changed arch_debug_save_registers() to take an arch-specific structure

arch_debug_registers instead.
* Call arch_debug_save_registers() on all CPUs when entering the kernel
  debugger.
* Added debug_get_debug_registers() to return a specified CPU's saved
  registers.
* x86:
  - Replaced the previous arch_debug_save_registers() implementation. Disabled
    getting the registers via the gdb interface for the time being.
  - Fixed the "sc", "call", and "calling" commands to also work for threads
    running on another CPU.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35907 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-03-18 17:20:06 +00:00
parent 74de61fda5
commit cfefeee3f8
15 changed files with 149 additions and 55 deletions
@@ -0,0 +1,16 @@
/*
* Copyright 2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_ARM_DEBUG_H
#define _KERNEL_ARCH_ARM_DEBUG_H
#include <SupportDefs.h>
struct arch_debug_registers {
};
#endif // _KERNEL_ARCH_ARM_DEBUG_H
+2 -1
View File
@@ -11,6 +11,7 @@
#include <SupportDefs.h>
#include <arch_debug.h>
#include <cpu.h>
@@ -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);
@@ -0,0 +1,16 @@
/*
* Copyright 2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_M68K_DEBUG_H
#define _KERNEL_ARCH_M68K_DEBUG_H
#include <SupportDefs.h>
struct arch_debug_registers {
};
#endif // _KERNEL_ARCH_M68K_DEBUG_H
@@ -0,0 +1,16 @@
/*
* Copyright 2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_MIPSEL_DEBUG_H
#define _KERNEL_ARCH_MIPSEL_DEBUG_H
#include <SupportDefs.h>
struct arch_debug_registers {
};
#endif // _KERNEL_ARCH_MIPSEL_DEBUG_H
@@ -0,0 +1,16 @@
/*
* Copyright 2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_PPC_DEBUG_H
#define _KERNEL_ARCH_PPC_DEBUG_H
#include <SupportDefs.h>
struct arch_debug_registers {
};
#endif // _KERNEL_ARCH_PPC_DEBUG_H
@@ -0,0 +1,17 @@
/*
* Copyright 2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_X86_DEBUG_H
#define _KERNEL_ARCH_X86_DEBUG_H
#include <SupportDefs.h>
struct arch_debug_registers {
uint32 ebp;
};
#endif // _KERNEL_ARCH_X86_DEBUG_H
+6 -2
View File
@@ -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);
+1 -1
View File
@@ -228,7 +228,7 @@ return 0;
void
arch_debug_save_registers(int *regs)
arch_debug_save_registers(struct arch_debug_registers* registers)
{
}
+1 -1
View File
@@ -248,7 +248,7 @@ return 0;
void
arch_debug_save_registers(int *regs)
arch_debug_save_registers(struct arch_debug_registers* registers)
{
}
+1 -1
View File
@@ -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
}
+1 -1
View File
@@ -254,7 +254,7 @@ return 0;
void
arch_debug_save_registers(int *regs)
arch_debug_save_registers(struct arch_debug_registers* registers)
{
}
+37 -4
View File
@@ -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))
-40
View File
@@ -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
+14 -4
View File
@@ -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)
{
+5
View File
@@ -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;
}