-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
[lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan #137904
Conversation
@llvm/pr-subscribers-lldb Author: Ely Ronnen (eronnen) ChangesExpose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan Full diff: https://github.com/llvm/llvm-project/pull/137904.diff 2 Files Affected:
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);
|
There was a problem hiding this 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.
Added tests |
✅ With the latest revision this PR passed the Python code formatter. |
d0f46d9
to
e535984
Compare
|
||
# Verify that stepping over an instruction doesn't step into `foo` | ||
frame = thread.GetFrameAtIndex(0) | ||
self.assertEqual("main", frame.GetFunctionName()) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
e535984
to
b061968
Compare
Added branch instructions asserts to the tests |
b061968
to
7ab3ffd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this 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...)
Removed the version without |
Also note that all the other |
Yes, we don't remove API's from the SB API set, which means we do get left with our mistakes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LEBTM
e8aa0cf
to
1faea15
Compare
@eronnen this is breaking the incremental green dragon bots. https://green.lab.llvm.org//job/as-lldb-cmake/25425/changes#41321416815d74a4a7fd15c78fcfa5af457625bb
|
current_instruction = target.ReadInstructions(frame.GetPCAddress(), 1)[0] | ||
self.assertEqual( | ||
lldb.eInstructionControlFlowKindCall, | ||
current_instruction.GetControlFlowKind(target), |
There was a problem hiding this comment.
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
This is only implemented for x86. Originally introduced in: #137904
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 |
This is only implemented for x86. Originally introduced in: llvm/llvm-project#137904
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. |
@felipepiovezan thanks for the temp fix, I'll try to understand the problem soon |
@slydiman Seems this buildbot is running |
@eronnen my fix does not seem to have worked |
Ah there were two tests here. I've disabled the other one too. |
2815653 20250508 fpiove.. [lldb] Disable test using GetControlFlowKind on arm (HEAD, llvm/main) |
@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? |
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 :) |
Expose
QueueThreadPlanForStepSingleInstruction
function to SBThreadPlan