diff --git a/headers/private/kernel/arch/debug.h b/headers/private/kernel/arch/debug.h index 6d79e579fc..17e9802023 100644 --- a/headers/private/kernel/arch/debug.h +++ b/headers/private/kernel/arch/debug.h @@ -23,7 +23,7 @@ status_t arch_debug_init(kernel_args *args); void *arch_debug_get_caller(void); int32 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, int32 skipIframes, int32 skipFrames, bool userOnly); -void *arch_debug_get_interrupt_pc(); +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 *); diff --git a/src/system/kernel/arch/m68k/arch_debug.cpp b/src/system/kernel/arch/m68k/arch_debug.cpp index a692cf3e58..c0d3b77e47 100644 --- a/src/system/kernel/arch/m68k/arch_debug.cpp +++ b/src/system/kernel/arch/m68k/arch_debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008, Haiku Inc. All rights reserved. + * Copyright 2003-2009, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -360,7 +360,7 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, void* -arch_debug_get_interrupt_pc() +arch_debug_get_interrupt_pc(bool* _isSyscall) { // TODO: Implement! return NULL; diff --git a/src/system/kernel/arch/ppc/arch_debug.cpp b/src/system/kernel/arch/ppc/arch_debug.cpp index b642946477..1d382bd863 100644 --- a/src/system/kernel/arch/ppc/arch_debug.cpp +++ b/src/system/kernel/arch/ppc/arch_debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008, Haiku Inc. All rights reserved. + * Copyright 2003-2009, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -296,7 +296,7 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, void* -arch_debug_get_interrupt_pc() +arch_debug_get_interrupt_pc(bool* _isSyscall) { // TODO: Implement! return NULL; diff --git a/src/system/kernel/arch/x86/arch_debug.cpp b/src/system/kernel/arch/x86/arch_debug.cpp index 3b8404f137..facc378050 100644 --- a/src/system/kernel/arch/x86/arch_debug.cpp +++ b/src/system/kernel/arch/x86/arch_debug.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -980,16 +981,21 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, /*! Returns the program counter of the currently debugged (respectively this) - thread where the innermost interrupts happened. Returns \c NULL, if there's - none or a problem occurred retrieving it. + thread where the innermost interrupts happened. \a _isSyscall, if specified, + is set to whether this interrupt frame was created by a syscall. Returns + \c NULL, if there's no such frame or a problem occurred retrieving it; + \a _isSyscall won't be set in this case. */ void* -arch_debug_get_interrupt_pc() +arch_debug_get_interrupt_pc(bool* _isSyscall) { struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); if (frame == NULL) return NULL; + if (_isSyscall != NULL) + *_isSyscall = frame->vector == 99; + return (void*)(addr_t)frame->eip; } diff --git a/src/system/kernel/debug/user_debugger.cpp b/src/system/kernel/debug/user_debugger.cpp index 719c03d6fe..b77117283a 100644 --- a/src/system/kernel/debug/user_debugger.cpp +++ b/src/system/kernel/debug/user_debugger.cpp @@ -798,8 +798,10 @@ thread_hit_debug_event(debug_debugger_message event, const void *message, prepare_debugger_change(team, debugChangeCondition); if (team->debug_info.breakpoint_manager != NULL) { - team->debug_info.breakpoint_manager->PrepareToContinue( - arch_debug_get_interrupt_pc()); + bool isSyscall; + void* pc = arch_debug_get_interrupt_pc(&isSyscall); + if (pc != NULL && !isSyscall) + team->debug_info.breakpoint_manager->PrepareToContinue(pc); } finish_debugger_change(team); @@ -1316,7 +1318,7 @@ profiling_do_sample(bool& flushBuffer) if (debugInfo.profile.last_image_event < imageEvent || debugInfo.profile.flush_threshold - sampleCount < stackDepth) { - if (!IS_KERNEL_ADDRESS(arch_debug_get_interrupt_pc())) { + if (!IS_KERNEL_ADDRESS(arch_debug_get_interrupt_pc(NULL))) { flushBuffer = true; return true; } @@ -1353,7 +1355,7 @@ profiling_do_sample(bool& flushBuffer) for (int32 i = count; i < stackDepth; i++) returnAddresses[i] = 0; } else - *returnAddresses = (addr_t)arch_debug_get_interrupt_pc(); + *returnAddresses = (addr_t)arch_debug_get_interrupt_pc(NULL); debugInfo.profile.sample_count += stackDepth; } diff --git a/src/system/kernel/scheduler/scheduler_tracing.h b/src/system/kernel/scheduler/scheduler_tracing.h index 2933558c34..a6929e0e87 100644 --- a/src/system/kernel/scheduler/scheduler_tracing.h +++ b/src/system/kernel/scheduler/scheduler_tracing.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -99,7 +99,7 @@ public: #if SCHEDULER_TRACING >= 2 if (fPreviousState == B_THREAD_READY) - fPreviousPC = arch_debug_get_interrupt_pc(); + fPreviousPC = arch_debug_get_interrupt_pc(NULL); else #endif fPreviousWaitObject = previous->wait.object;