https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137904
>From b901b71abbaac768e67913cdbc15da2337c8bb03 Mon Sep 17 00:00:00 2001 From: Ely Ronnen <elyron...@gmail.com> Date: Wed, 30 Apr 2025 02:00:44 +0200 Subject: [PATCH 1/4] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan --- lldb/include/lldb/API/SBThreadPlan.h | 4 ++++ lldb/source/API/SBThreadPlan.cpp | 31 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lldb/include/lldb/API/SBThreadPlan.h b/lldb/include/lldb/API/SBThreadPlan.h index d02ab80f76a76..ce1a1078d69b9 100644 --- a/lldb/include/lldb/API/SBThreadPlan.h +++ b/lldb/include/lldb/API/SBThreadPlan.h @@ -105,6 +105,10 @@ class LLDB_API SBThreadPlan { SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn, SBError &error); + SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over); + SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over, + SBError &error); + SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address); SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address, SBError &error); diff --git a/lldb/source/API/SBThreadPlan.cpp b/lldb/source/API/SBThreadPlan.cpp index 083a050de8a38..a85afbb043875 100644 --- a/lldb/source/API/SBThreadPlan.cpp +++ b/lldb/source/API/SBThreadPlan.cpp @@ -325,6 +325,37 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, return SBThreadPlan(); } +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over) { + LLDB_INSTRUMENT_VA(this, step_over); + + SBError error; + return QueueThreadPlanForStepSingleInstruction(step_over, error); +} + +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); >From 8d8f4d7edbff13de7f07853700ab717ef275e3da Mon Sep 17 00:00:00 2001 From: Ely Ronnen <elyron...@gmail.com> Date: Wed, 30 Apr 2025 09:37:32 +0200 Subject: [PATCH 2/4] Add API tests for QueueThreadPlanForStepSingleInstruction --- .../functionalities/step_scripted/Steps.py | 16 +++++++++++ .../step_scripted/TestStepScripted.py | 28 +++++++++++++++++++ .../API/functionalities/step_scripted/main.c | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py index 3325dba753657..e9e0fae1b14be 100644 --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -45,6 +45,22 @@ def queue_child_thread_plan(self): 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) + + +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) + + # This plan does a step-over until a variable changes value. class StepUntil(StepWithChild): def __init__(self, thread_plan, args_data): diff --git a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py index 53901718019f9..f65c366a09e87 100644 --- a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py +++ b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py @@ -44,6 +44,34 @@ def step_out_with_scripted_plan(self, name): stop_desc = thread.GetStopDescription(1000) self.assertIn("Stepping out from", stop_desc, "Got right description") + def test_step_single_instruction(self): + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "Break on foo call", self.main_source_file + ) + + 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): + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "Break on foo call", self.main_source_file + ) + + 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()) + def test_misspelled_plan_name(self): """Test that we get a useful error if we misspell the plan class name""" self.build() diff --git a/lldb/test/API/functionalities/step_scripted/main.c b/lldb/test/API/functionalities/step_scripted/main.c index bfd8a35d55626..499a999e699d0 100644 --- a/lldb/test/API/functionalities/step_scripted/main.c +++ b/lldb/test/API/functionalities/step_scripted/main.c @@ -8,6 +8,6 @@ void foo() { } int main() { - foo(); + foo(); // Break on foo call. return 0; } >From 7ab3ffdff562751c7398a48c4aa1c68bb6a87198 Mon Sep 17 00:00:00 2001 From: Ely Ronnen <elyron...@gmail.com> Date: Wed, 30 Apr 2025 22:32:57 +0200 Subject: [PATCH 3/4] improve QueueThreadPlanForStepSingleInstruction tests --- .../step_scripted/TestStepScripted.py | 26 ++++++++++++++----- .../API/functionalities/step_scripted/main.c | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py index f65c366a09e87..54bc154590ed0 100644 --- a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py +++ b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py @@ -44,11 +44,23 @@ def step_out_with_scripted_plan(self, name): stop_desc = thread.GetStopDescription(1000) self.assertIn("Stepping out from", stop_desc, "Got right description") - def test_step_single_instruction(self): + def run_until_branch_instruction(self): self.build() (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( - self, "Break on foo call", self.main_source_file + 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) @@ -58,10 +70,11 @@ def test_step_single_instruction(self): self.assertEqual("foo", frame.GetFunctionName()) def test_step_single_instruction_with_step_over(self): - self.build() - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( - self, "Break on foo call", self.main_source_file - ) + (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" @@ -71,6 +84,7 @@ def test_step_single_instruction_with_step_over(self): # 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""" diff --git a/lldb/test/API/functionalities/step_scripted/main.c b/lldb/test/API/functionalities/step_scripted/main.c index 499a999e699d0..9023120c44312 100644 --- a/lldb/test/API/functionalities/step_scripted/main.c +++ b/lldb/test/API/functionalities/step_scripted/main.c @@ -8,6 +8,6 @@ void foo() { } int main() { - foo(); // Break on foo call. + foo(); // Break on branch instruction. return 0; } >From 9dd1ad032d55625b71e9fdd55449e5b937f1e225 Mon Sep 17 00:00:00 2001 From: Ely Ronnen <elyron...@gmail.com> Date: Thu, 1 May 2025 21:52:11 +0200 Subject: [PATCH 4/4] force QueueThreadPlanForStepSingleInstruction to accept SBError --- lldb/include/lldb/API/SBThreadPlan.h | 1 - lldb/source/API/SBThreadPlan.cpp | 8 -------- lldb/test/API/functionalities/step_scripted/Steps.py | 4 ++-- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/lldb/include/lldb/API/SBThreadPlan.h b/lldb/include/lldb/API/SBThreadPlan.h index ce1a1078d69b9..1f0164efcfb98 100644 --- a/lldb/include/lldb/API/SBThreadPlan.h +++ b/lldb/include/lldb/API/SBThreadPlan.h @@ -105,7 +105,6 @@ class LLDB_API SBThreadPlan { SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn, SBError &error); - SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over); SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over, SBError &error); diff --git a/lldb/source/API/SBThreadPlan.cpp b/lldb/source/API/SBThreadPlan.cpp index a85afbb043875..c8ca6c81a3efb 100644 --- a/lldb/source/API/SBThreadPlan.cpp +++ b/lldb/source/API/SBThreadPlan.cpp @@ -325,14 +325,6 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, return SBThreadPlan(); } -SBThreadPlan -SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over) { - LLDB_INSTRUMENT_VA(this, step_over); - - SBError error; - return QueueThreadPlanForStepSingleInstruction(step_over, error); -} - SBThreadPlan SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over, SBError &error) { diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py index e9e0fae1b14be..bf4c1f38cbbb3 100644 --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -50,7 +50,7 @@ def __init__(self, thread_plan, dict): super().__init__(thread_plan) def queue_child_thread_plan(self): - return self.thread_plan.QueueThreadPlanForStepSingleInstruction(False) + return self.thread_plan.QueueThreadPlanForStepSingleInstruction(False, lldb.SBError()) class StepSingleInstructionWithStepOver(StepWithChild): @@ -58,7 +58,7 @@ def __init__(self, thread_plan, dict): super().__init__(thread_plan) def queue_child_thread_plan(self): - return self.thread_plan.QueueThreadPlanForStepSingleInstruction(True) + return self.thread_plan.QueueThreadPlanForStepSingleInstruction(True, lldb.SBError()) # This plan does a step-over until a variable changes value. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits