Skip to content

[lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan #137904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

eronnen
Copy link
Contributor

@eronnen eronnen commented Apr 30, 2025

Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan

@eronnen eronnen requested a review from JDevlieghere as a code owner April 30, 2025 00:01
@llvmbot llvmbot added the lldb label Apr 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 30, 2025

@llvm/pr-subscribers-lldb

Author: Ely Ronnen (eronnen)

Changes

Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan


Full diff: https://github.com/llvm/llvm-project/pull/137904.diff

2 Files Affected:

  • (modified) lldb/include/lldb/API/SBThreadPlan.h (+4)
  • (modified) lldb/source/API/SBThreadPlan.cpp (+31)
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);

Copy link
Collaborator

@jimingham jimingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can compose the single step out of the range plans with the range chosen appropriately, but that seems annoying, and this is a pretty useful operation. So adding it is a good idea.

The code looks fine.

Needs a test, however.

@eronnen
Copy link
Contributor Author

eronnen commented Apr 30, 2025

Added tests

@eronnen eronnen requested a review from jimingham April 30, 2025 07:37
Copy link

github-actions bot commented Apr 30, 2025

✅ With the latest revision this PR passed the Python code formatter.

@eronnen eronnen force-pushed the lldb-expose-queue-thread-plan-for-single-instruction branch from d0f46d9 to e535984 Compare April 30, 2025 07:42

# Verify that stepping over an instruction doesn't step into `foo`
frame = thread.GetFrameAtIndex(0)
self.assertEqual("main", frame.GetFunctionName())
Copy link
Collaborator

@jimingham jimingham Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the thread plan failed to move at all, this assert would pass. Figuring out where you go with nexti over a function call is a little trickier than stepi, so it's probably okay here to just assert that you didn't step into foo but the PC did change.

Copy link
Collaborator

@jimingham jimingham Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might also assert before the nexti that you really are at a branch (you can get the instruction list for the function, find the instruction you are stopped at and ask it IsBranch. It seems really unlikely that any compiler/architecture would would emit more than a single branch and link for a call to a void (*)(void), but it's better not to rely on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense, I didn't have any other straightfoward idea for a 100% way to break on a branch instruction but adding a check is a good idea


# Verify that stepping a single instruction after "foo();" steps into `foo`
frame = thread.GetFrameAtIndex(0)
self.assertEqual("foo", frame.GetFunctionName())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of step-i, we are really trying to assert that we step just one instruction. That's actually not all that hard to test exactly. Just add some simple arithmetic computation to the test, so it won't have branches, and then stop at the beginning of the computation, run your step-i plan, and assert that you did get to the NEXT instruction on the instruction list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that testing a branch is more powerful though, because in a case of a non branch instruction both stepi and nexti would step into the same instruction

@eronnen eronnen force-pushed the lldb-expose-queue-thread-plan-for-single-instruction branch from e535984 to b061968 Compare April 30, 2025 20:35
@eronnen
Copy link
Contributor Author

eronnen commented Apr 30, 2025

Added branch instructions asserts to the tests

@eronnen eronnen requested a review from jimingham April 30, 2025 20:37
@eronnen eronnen force-pushed the lldb-expose-queue-thread-plan-for-single-instruction branch from b061968 to 7ab3ffd Compare April 30, 2025 21:10
Copy link
Collaborator

@jimingham jimingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@jimingham jimingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for more round trips, but can you remove the no-SBError overload. Adding that was really a poor choice on my part (which I seem to want to repeat for some reason...)

@eronnen
Copy link
Contributor Author

eronnen commented May 1, 2025

Removed the version without SBError, but I'm not sure what to do with it in the python test because this function is not called in the test body, so we can't assert it

@eronnen
Copy link
Contributor Author

eronnen commented May 1, 2025

Also note that all the other QueueThreadPlanFor* functions still have a version without SBError :/

@eronnen eronnen requested a review from jimingham May 1, 2025 20:09
@jimingham
Copy link
Collaborator

Also note that all the other QueueThreadPlanFor* functions still have a version without SBError :/

Yes, we don't remove API's from the SB API set, which means we do get left with our mistakes.

Copy link
Collaborator

@jimingham jimingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LEBTM

@eronnen eronnen force-pushed the lldb-expose-queue-thread-plan-for-single-instruction branch from e8aa0cf to 1faea15 Compare May 7, 2025 20:01
@eronnen eronnen merged commit 4132141 into llvm:main May 8, 2025
10 checks passed
@felipepiovezan
Copy link
Contributor

felipepiovezan commented May 8, 2025

@eronnen this is breaking the incremental green dragon bots.
Could you revert while you look at this please?

https://green.lab.llvm.org//job/as-lldb-cmake/25425/changes#41321416815d74a4a7fd15c78fcfa5af457625bb

[2025-05-08T12:15:32.021Z] ======================================================================
[2025-05-08T12:15:32.021Z] FAIL: test_step_single_instruction (TestStepScripted.StepScriptedTestCase)
[2025-05-08T12:15:32.021Z] ----------------------------------------------------------------------
[2025-05-08T12:15:32.021Z] Traceback (most recent call last):
[2025-05-08T12:15:32.021Z]   File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/step_scripted/TestStepScripted.py", line 63, in test_step_single_instruction
[2025-05-08T12:15:32.021Z]     (target, process, thread, bkpt) = self.run_until_branch_instruction()
[2025-05-08T12:15:32.021Z]   File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/step_scripted/TestStepScripted.py", line 56, in run_until_branch_instruction
[2025-05-08T12:15:32.021Z]     self.assertEqual(
[2025-05-08T12:15:32.021Z] AssertionError: 2 != 0
[2025-05-08T12:15:32.021Z] Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang

current_instruction = target.ReadInstructions(frame.GetPCAddress(), 1)[0]
self.assertEqual(
lldb.eInstructionControlFlowKindCall,
current_instruction.GetControlFlowKind(target),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I don't think is implemented for arm targets

felipepiovezan added a commit that referenced this pull request May 8, 2025
This is only implemented for x86.
Originally introduced in: #137904
@felipepiovezan
Copy link
Contributor

To fix the bots, I've disabled your new test in all non x86 archs, feel free to update if you want to do something else

llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request May 8, 2025
This is only implemented for x86.
Originally introduced in: llvm/llvm-project#137904
@slydiman
Copy link
Contributor

slydiman commented May 8, 2025

The following buildbots are broken by this patch too

https://lab.llvm.org/buildbot/#/builders/195/builds/8715

https://lab.llvm.org/buildbot/#/builders/197/builds/5054

Please fix ASAP.

@eronnen
Copy link
Contributor Author

eronnen commented May 8, 2025

@felipepiovezan thanks for the temp fix, I'll try to understand the problem soon

@eronnen
Copy link
Contributor Author

eronnen commented May 8, 2025

@slydiman Seems this buildbot is running aarch64 so this test should be disabled after @felipepiovezan 's fix.

@felipepiovezan
Copy link
Contributor

@eronnen my fix does not seem to have worked

@felipepiovezan
Copy link
Contributor

Ah there were two tests here. I've disabled the other one too.

@felipepiovezan
Copy link
Contributor

2815653 20250508 fpiove.. [lldb] Disable test using GetControlFlowKind on arm (HEAD, llvm/main)

@eronnen
Copy link
Contributor Author

eronnen commented May 8, 2025

@felipepiovezan Sorry for the trouble, do you know if there's a way for me to run the CI on arm/aarch64 before merging the PR next time?

@DavidSpickett
Copy link
Collaborator

At this time there is no pre-merge CI for Arm. If you feel like hacking something together, it is possible to use Github's Runners to test it on your own fork. I hope to make that route more user friendly at some point, and expand the automatic CI to Arm when we can.

Fix ups after landing are a fact of life for the time being :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants