* Added some debug output for stepping.
* Fixed incorrect "step over" handling after hitting the temporary breakpoint. Could cause stepping into functions. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31673 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -109,6 +109,7 @@ ThreadHandler::HandleBreakpointHit(BreakpointHitEvent* event)
|
|||||||
{
|
{
|
||||||
CpuState* cpuState = event->GetCpuState();
|
CpuState* cpuState = event->GetCpuState();
|
||||||
target_addr_t instructionPointer = cpuState->InstructionPointer();
|
target_addr_t instructionPointer = cpuState->InstructionPointer();
|
||||||
|
printf("ThreadHandler::HandleBreakpointHit(): ip: %llx\n", instructionPointer);
|
||||||
|
|
||||||
// check whether this is a temporary breakpoint we're waiting for
|
// check whether this is a temporary breakpoint we're waiting for
|
||||||
if (fBreakpointAddress != 0 && instructionPointer == fBreakpointAddress
|
if (fBreakpointAddress != 0 && instructionPointer == fBreakpointAddress
|
||||||
@@ -225,6 +226,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
|
|||||||
case MSG_THREAD_STEP_OUT:
|
case MSG_THREAD_STEP_OUT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
printf("ThreadHandler::HandleThreadAction(MSG_THREAD_STEP_*)\n");
|
||||||
|
|
||||||
// We want to step. We need a stack trace for that purpose. If we don't
|
// We want to step. We need a stack trace for that purpose. If we don't
|
||||||
// have one yet, get it. Start with the CPU state.
|
// have one yet, get it. Start with the CPU state.
|
||||||
@@ -246,16 +248,13 @@ ThreadHandler::HandleThreadAction(uint32 action)
|
|||||||
}
|
}
|
||||||
|
|
||||||
StackFrame* frame = stackTrace->FrameAt(0);
|
StackFrame* frame = stackTrace->FrameAt(0);
|
||||||
|
printf(" ip: %#llx\n", frame->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 return by means of a breakpoint.
|
// when it return by means of a breakpoint.
|
||||||
if (frame->Type() == STACK_FRAME_TYPE_SYSCALL) {
|
if (frame->Type() == STACK_FRAME_TYPE_SYSCALL) {
|
||||||
// set a breakpoint at the CPU state's instruction pointer (points to
|
// set a breakpoint at the CPU state's instruction pointer (points to
|
||||||
// the return address, unlike the stack frame's instruction pointer)
|
// the return address, unlike the stack frame's instruction pointer)
|
||||||
// TODO: That's OK in principle, but needs additional work with recursive
|
|
||||||
// functions. We need to store some information that allows us to determine
|
|
||||||
// whether we've actually stepped out of the current frame when we have hit
|
|
||||||
// the breakpoint.
|
|
||||||
status_t error = _InstallTemporaryBreakpoint(
|
status_t error = _InstallTemporaryBreakpoint(
|
||||||
frame->GetCpuState()->InstructionPointer());
|
frame->GetCpuState()->InstructionPointer());
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
@@ -270,6 +269,10 @@ ThreadHandler::HandleThreadAction(uint32 action)
|
|||||||
|
|
||||||
// For "step out" just set a temporary breakpoint on the return address.
|
// For "step out" just set a temporary breakpoint on the return address.
|
||||||
if (action == MSG_THREAD_STEP_OUT) {
|
if (action == MSG_THREAD_STEP_OUT) {
|
||||||
|
// TODO: That's OK in principle, but needs additional work with recursive
|
||||||
|
// functions. We need to store some information that allows us to determine
|
||||||
|
// whether we've actually stepped out of the current frame when we have hit
|
||||||
|
// the breakpoint.
|
||||||
status_t error = _InstallTemporaryBreakpoint(frame->ReturnAddress());
|
status_t error = _InstallTemporaryBreakpoint(frame->ReturnAddress());
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
_StepFallback();
|
_StepFallback();
|
||||||
@@ -288,6 +291,8 @@ ThreadHandler::HandleThreadAction(uint32 action)
|
|||||||
_StepFallback();
|
_StepFallback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
printf(" statement: %#llx - %#llx\n", fStepStatement->CoveringAddressRange().Start(),
|
||||||
|
fStepStatement->CoveringAddressRange().End());
|
||||||
|
|
||||||
if (action == MSG_THREAD_STEP_INTO) {
|
if (action == MSG_THREAD_STEP_INTO) {
|
||||||
// step into
|
// step into
|
||||||
@@ -426,6 +431,7 @@ ThreadHandler::_StepFallback()
|
|||||||
bool
|
bool
|
||||||
ThreadHandler::_DoStepOver(CpuState* cpuState)
|
ThreadHandler::_DoStepOver(CpuState* cpuState)
|
||||||
{
|
{
|
||||||
|
printf("ThreadHandler::_DoStepOver()\n");
|
||||||
// The basic strategy is to single-step out of the statement like for
|
// The basic strategy is to single-step out of the statement like for
|
||||||
// "step into", only we have to avoid stepping into subroutines. Hence we
|
// "step into", only we have to avoid stepping into subroutines. Hence we
|
||||||
// check whether the current instruction is a subroutine call. If not, we
|
// check whether the current instruction is a subroutine call. If not, we
|
||||||
@@ -433,14 +439,18 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
|
|||||||
InstructionInfo info;
|
InstructionInfo info;
|
||||||
if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
|
if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
|
||||||
cpuState->InstructionPointer(), info) != B_OK) {
|
cpuState->InstructionPointer(), info) != B_OK) {
|
||||||
|
printf(" failed to get instruction info\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Type() != INSTRUCTION_TYPE_SUBROUTINE_CALL) {
|
if (info.Type() != INSTRUCTION_TYPE_SUBROUTINE_CALL) {
|
||||||
_SingleStepThread(cpuState->InstructionPointer());
|
_SingleStepThread(cpuState->InstructionPointer());
|
||||||
|
printf(" not a subroutine call\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf(" subroutine call -- installing breakpoint at address %#llx\n",
|
||||||
|
info.Address() + info.Size());
|
||||||
if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
|
if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -520,7 +530,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
|
|||||||
// otherwise we're done.
|
// otherwise we're done.
|
||||||
if (fStepStatement->ContainsAddress(
|
if (fStepStatement->ContainsAddress(
|
||||||
cpuState->InstructionPointer())) {
|
cpuState->InstructionPointer())) {
|
||||||
_SingleStepThread(cpuState->InstructionPointer());
|
if (!_DoStepOver(cpuState))
|
||||||
|
_StepFallback();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -538,6 +549,7 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
|
|||||||
bool
|
bool
|
||||||
ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
|
ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
|
||||||
{
|
{
|
||||||
|
printf("ThreadHandler::_HandleSingleStepStep(): ip: %llx\n", cpuState->InstructionPointer());
|
||||||
switch (fStepMode) {
|
switch (fStepMode) {
|
||||||
case STEP_INTO:
|
case STEP_INTO:
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user