Fix incorrect return value problem in STEP_OUT.

A similar problem to that described in my previous commit afflicted the
step out case as well. We now store the current IP when issuing a step
out, and use that as the function address once execution returns.
This commit is contained in:
Rene Gollent
2013-05-11 19:08:09 -04:00
parent d9d42ec6bf
commit 3f3ade6223
@@ -269,6 +269,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
TRACE_CONTROL(" ip: %#" B_PRIx64 "\n", frame->InstructionPointer()); TRACE_CONTROL(" ip: %#" B_PRIx64 "\n", frame->InstructionPointer());
target_addr_t frameIP = frame->GetCpuState()->InstructionPointer();
// When the thread is in a syscall, do the same for all step kinds: Stop it // When the thread is in a syscall, do the same for all step kinds: Stop it
// when it returns by means of a breakpoint. // when it returns by means of a breakpoint.
if (frame->Type() == STACK_FRAME_TYPE_SYSCALL) { if (frame->Type() == STACK_FRAME_TYPE_SYSCALL) {
@@ -284,15 +285,14 @@ ThreadHandler::HandleThreadAction(uint32 action)
// The second issue is that the temporary breakpoint is probably not necessary // The second issue is that the temporary breakpoint is probably not necessary
// anymore, since single-stepping over "syscall" instructions should just work // anymore, since single-stepping over "syscall" instructions should just work
// as expected. // as expected.
status_t error = _InstallTemporaryBreakpoint( status_t error = _InstallTemporaryBreakpoint(frameIP);
frame->GetCpuState()->InstructionPointer());
if (error != B_OK) { if (error != B_OK) {
_StepFallback(); _StepFallback();
return; return;
} }
fStepMode = STEP_OUT; fStepMode = STEP_OUT;
_RunThread(frame->GetCpuState()->InstructionPointer()); _RunThread(frameIP);
return; return;
} }
@@ -303,9 +303,10 @@ ThreadHandler::HandleThreadAction(uint32 action)
_StepFallback(); _StepFallback();
return; return;
} }
fPreviousInstructionPointer = frameIP;
fPreviousFrameAddress = frame->FrameAddress(); fPreviousFrameAddress = frame->FrameAddress();
fStepMode = STEP_OUT; fStepMode = STEP_OUT;
_RunThread(frame->GetCpuState()->InstructionPointer()); _RunThread(frameIP);
return; return;
} }
@@ -324,7 +325,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
if (action == MSG_THREAD_STEP_INTO) { if (action == MSG_THREAD_STEP_INTO) {
// step into // step into
fStepMode = STEP_INTO; fStepMode = STEP_INTO;
_SingleStepThread(frame->GetCpuState()->InstructionPointer()); _SingleStepThread(frameIP);
} else { } else {
fPreviousFrameAddress = frame->FrameAddress(); fPreviousFrameAddress = frame->FrameAddress();
// step over // step over
@@ -648,7 +649,7 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
" - step out adding return value\n", cpuState " - step out adding return value\n", cpuState
->StackFramePointer(), fPreviousFrameAddress); ->StackFramePointer(), fPreviousFrameAddress);
ReturnValueInfo* info = new(std::nothrow) ReturnValueInfo( ReturnValueInfo* info = new(std::nothrow) ReturnValueInfo(
cpuState->InstructionPointer(), cpuState); fPreviousInstructionPointer, cpuState);
if (info == NULL) if (info == NULL)
return false; return false;
BReference<ReturnValueInfo> infoReference(info, true); BReference<ReturnValueInfo> infoReference(info, true);