From 118ddee0fdddd28bb953d559713a8da1bcd0d06e Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 14 Dec 2011 22:27:38 -0500 Subject: [PATCH] Adjust ThreadHandler's usage of CreateStackTrace(). - Limit invocations of CreateStackTrace() in ThreadHandler to only unwind the topmost frame since that's all it actually cares about anyways. Also adjust Step Over to use this functionality in order to work with the correct frame addresses, since the CPU frame pointer register isn't entirely what we want here. --- src/apps/debugger/ThreadHandler.cpp | 42 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/apps/debugger/ThreadHandler.cpp b/src/apps/debugger/ThreadHandler.cpp index 19450f933e..c1932f2ebb 100644 --- a/src/apps/debugger/ThreadHandler.cpp +++ b/src/apps/debugger/ThreadHandler.cpp @@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace) == B_OK) { + fThread->GetTeam(), this, cpuState, stackTrace, 1) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } } @@ -324,7 +324,7 @@ ThreadHandler::HandleThreadAction(uint32 action) fStepMode = STEP_INTO; _SingleStepThread(frame->GetCpuState()->InstructionPointer()); } else { - fPreviousFrameAddress = cpuState->StackFramePointer(); + fPreviousFrameAddress = frame->FrameAddress(); // step over fStepMode = STEP_OVER; if (!_DoStepOver(frame->GetCpuState())) @@ -559,17 +559,32 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState) switch (fStepMode) { case STEP_OVER: { - // If we're not in the same frame we started in, keep executing. - if (cpuState->StackFramePointer() != fPreviousFrameAddress) - { - status_t error = _InstallTemporaryBreakpoint( - cpuState->InstructionPointer()); - if (error != B_OK) - _StepFallback(); - else - _RunThread(cpuState->InstructionPointer()); - return true; + StackTrace* stackTrace = fThread->GetStackTrace(); + BReference stackTraceReference(stackTrace); + + if (stackTrace == NULL && cpuState != NULL) { + if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( + fThread->GetTeam(), this, cpuState, stackTrace, 1) + == B_OK) { + stackTraceReference.SetTo(stackTrace, true); + } } + if (stackTrace != NULL) { + StackFrame* frame = stackTrace->FrameAt(0); + // If we're not in the same frame we started in, + // keep executing. + if (frame != NULL && fPreviousFrameAddress + != stackTrace->FrameAt(0)->FrameAddress()) { + status_t error = _InstallTemporaryBreakpoint( + cpuState->InstructionPointer()); + if (error != B_OK) + _StepFallback(); + else + _RunThread(cpuState->InstructionPointer()); + return true; + } + } + // If we're still in the statement, we continue single-stepping, // otherwise we're done. if (fStepStatement->ContainsAddress( @@ -635,7 +650,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace) == B_OK) { + fThread->GetTeam(), this, cpuState, stackTrace, 1) + == B_OK) { stackTraceReference.SetTo(stackTrace, true); } }