[lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan (#137904)
Expose `QueueThreadPlanForStepSingleInstruction` function to SBThreadPlan
This commit is contained in:
parent
c290f48a45
commit
4132141681
@ -105,6 +105,9 @@ public:
|
||||
SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
|
||||
bool first_insn, SBError &error);
|
||||
|
||||
SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over,
|
||||
SBError &error);
|
||||
|
||||
SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address);
|
||||
SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address,
|
||||
SBError &error);
|
||||
|
@ -325,6 +325,29 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
|
||||
return SBThreadPlan();
|
||||
}
|
||||
|
||||
SBThreadPlan
|
||||
SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over,
|
||||
SBError &error) {
|
||||
LLDB_INSTRUMENT_VA(this, step_over, error);
|
||||
|
||||
ThreadPlanSP thread_plan_sp(GetSP());
|
||||
if (thread_plan_sp) {
|
||||
Status plan_status;
|
||||
SBThreadPlan plan(
|
||||
thread_plan_sp->GetThread().QueueThreadPlanForStepSingleInstruction(
|
||||
step_over, false, false, plan_status));
|
||||
|
||||
if (plan_status.Fail())
|
||||
error.SetErrorString(plan_status.AsCString());
|
||||
else
|
||||
plan.GetSP()->SetPrivate(true);
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
return SBThreadPlan();
|
||||
}
|
||||
|
||||
SBThreadPlan
|
||||
SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) {
|
||||
LLDB_INSTRUMENT_VA(this, sb_address);
|
||||
|
@ -45,6 +45,26 @@ class StepScripted(StepWithChild):
|
||||
return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut")
|
||||
|
||||
|
||||
class StepSingleInstruction(StepWithChild):
|
||||
def __init__(self, thread_plan, dict):
|
||||
super().__init__(thread_plan)
|
||||
|
||||
def queue_child_thread_plan(self):
|
||||
return self.thread_plan.QueueThreadPlanForStepSingleInstruction(
|
||||
False, lldb.SBError()
|
||||
)
|
||||
|
||||
|
||||
class StepSingleInstructionWithStepOver(StepWithChild):
|
||||
def __init__(self, thread_plan, dict):
|
||||
super().__init__(thread_plan)
|
||||
|
||||
def queue_child_thread_plan(self):
|
||||
return self.thread_plan.QueueThreadPlanForStepSingleInstruction(
|
||||
True, lldb.SBError()
|
||||
)
|
||||
|
||||
|
||||
# This plan does a step-over until a variable changes value.
|
||||
class StepUntil(StepWithChild):
|
||||
def __init__(self, thread_plan, args_data):
|
||||
|
@ -44,6 +44,48 @@ class StepScriptedTestCase(TestBase):
|
||||
stop_desc = thread.GetStopDescription(1000)
|
||||
self.assertIn("Stepping out from", stop_desc, "Got right description")
|
||||
|
||||
def run_until_branch_instruction(self):
|
||||
self.build()
|
||||
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
|
||||
self, "Break on branch instruction", self.main_source_file
|
||||
)
|
||||
|
||||
# Check that we landed in a call instruction
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
current_instruction = target.ReadInstructions(frame.GetPCAddress(), 1)[0]
|
||||
self.assertEqual(
|
||||
lldb.eInstructionControlFlowKindCall,
|
||||
current_instruction.GetControlFlowKind(target),
|
||||
)
|
||||
return (target, process, thread, bkpt)
|
||||
|
||||
def test_step_single_instruction(self):
|
||||
(target, process, thread, bkpt) = self.run_until_branch_instruction()
|
||||
|
||||
err = thread.StepUsingScriptedThreadPlan("Steps.StepSingleInstruction")
|
||||
self.assertSuccess(err)
|
||||
|
||||
# Verify that stepping a single instruction after "foo();" steps into `foo`
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
self.assertEqual("foo", frame.GetFunctionName())
|
||||
|
||||
def test_step_single_instruction_with_step_over(self):
|
||||
(target, process, thread, bkpt) = self.run_until_branch_instruction()
|
||||
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
next_instruction = target.ReadInstructions(frame.GetPCAddress(), 2)[1]
|
||||
next_instruction_address = next_instruction.GetAddress()
|
||||
|
||||
err = thread.StepUsingScriptedThreadPlan(
|
||||
"Steps.StepSingleInstructionWithStepOver"
|
||||
)
|
||||
self.assertSuccess(err)
|
||||
|
||||
# Verify that stepping over an instruction doesn't step into `foo`
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
self.assertEqual("main", frame.GetFunctionName())
|
||||
self.assertEqual(next_instruction_address, frame.GetPCAddress())
|
||||
|
||||
def test_misspelled_plan_name(self):
|
||||
"""Test that we get a useful error if we misspell the plan class name"""
|
||||
self.build()
|
||||
|
@ -8,6 +8,6 @@ void foo() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
foo();
|
||||
foo(); // Break on branch instruction.
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user