Skip to content

Add docs describing how the thread plan stack affects stepping #110167

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

Merged
merged 2 commits into from
Sep 27, 2024

Conversation

jimingham
Copy link
Collaborator

This is a convenient little feature of lldb, but if you didn't know it was there you'd likely never discover it.

@llvmbot
Copy link
Member

llvmbot commented Sep 26, 2024

@llvm/pr-subscribers-lldb

Author: None (jimingham)

Changes

This is a convenient little feature of lldb, but if you didn't know it was there you'd likely never discover it.


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

1 Files Affected:

  • (modified) lldb/docs/use/tutorial.rst (+27)
diff --git a/lldb/docs/use/tutorial.rst b/lldb/docs/use/tutorial.rst
index 00e7befdd087a4..57bf6c4479801e 100644
--- a/lldb/docs/use/tutorial.rst
+++ b/lldb/docs/use/tutorial.rst
@@ -536,6 +536,33 @@ This command will run the thread in the current frame until it reaches line 100
 in this frame or stops if it leaves the current frame. This is a pretty close
 equivalent to GDB's ``until`` command.
 
+One other useful thing to note about the lldb stepping commands is that they
+are implemented as a stack of interruptible operations.  Until the operation -
+e.g. step to the next line - is completed, the operation will remain on the
+stack.  If it is interrupted, new stepping commands will result in their
+operations being pushed onto the stack, each of them retired as they are completed.
+
+Suppose, for instance, you ``step-over`` a source line, and hit a breakpoint
+in a function called by the code of the line you are stepping over.  Since the step-over
+operation remains on the stack, you can examine the state at
+the point of the breakpoint hit, step around in that frame, step in to other
+frames, hit other breakpoints, etc.  Then when you are done, a simple ``continue``
+will resume the original ``step-over`` operation, only ending when the desired line is reached.
+This saves you from having to manually issue some number of ``step-out`` commands
+to get back to the frame you were stepping over.
+
+Hand-called functions using the ``expr`` command are also implemented by
+operations on this same stack.  So if you are calling some code with the ``expr`` command,
+and hit a breakpoint during the evaluation of that code, you can examine
+the state where you stopped, step around at your convenience, and then issue a
+``continue`` which will finish the expression evaluation operation and print the function
+result.
+
+You can examine the state of the operations stack using the ``thread plan list``
+command, and if, for instance, you decide you don't actually want that outermost
+next to continue running, you can remove it with the ``thread plan discard``
+command.
+
 A process, by default, will share the LLDB terminal with the inferior process.
 When in this mode, much like when debugging with GDB, when the process is
 running anything you type will go to the ``STDIN`` of the inferior process. To

@chelcassanova chelcassanova self-requested a review September 26, 2024 22:16
@chelcassanova
Copy link
Contributor

Adding myself as a reviewer here, I didn't know about either of these commands and the behaviour described here is something I've noticed without knowing exactly what was happening 😅 . The explanation for the docs looks good here so this LGTM.

Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

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

LGTM, a few minor suggestions but nothing of great importance. Thanks for writing this up!

@@ -536,6 +536,33 @@ This command will run the thread in the current frame until it reaches line 100
in this frame or stops if it leaves the current frame. This is a pretty close
equivalent to GDB's ``until`` command.

One other useful thing to note about the lldb stepping commands is that they
are implemented as a stack of interruptible operations. Until the operation -
e.g. step to the next line - is completed, the operation will remain on the
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: Until the operation - ... - is completed, it will remain ...

You have the operation written multiple times here, I think it will flow better if you shorten that one.

Copy link
Contributor

@felipepiovezan felipepiovezan Sep 27, 2024

Choose a reason for hiding this comment

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

At the risk of releasing the bike-shedding kraken, I personally dislike some pronouns in technical docs. It's very easy to accidentally create ambiguity with pronouns, whereas repetition of the noun is always precise. Your suggestion is safe though

One other useful thing to note about the lldb stepping commands is that they
are implemented as a stack of interruptible operations. Until the operation -
e.g. step to the next line - is completed, the operation will remain on the
stack. If it is interrupted, new stepping commands will result in their
Copy link
Member

Choose a reason for hiding this comment

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

I'm not 100% clear on what this sentence means. To confirm my understanding, you're trying to say something like "Interrupting a thread's execution doesn't clear the stack and running further stepping commands after that will push more operations to the stack". Is that right?

operations being pushed onto the stack, each of them retired as they are completed.

Suppose, for instance, you ``step-over`` a source line, and hit a breakpoint
in a function called by the code of the line you are stepping over. Since the step-over
Copy link
Member

Choose a reason for hiding this comment

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

There's a lot of qualifiers in the second clause of the first sentence. I think you could rephrase it as something like this.
Suggestion:

Suppose, for instance, you `step-over` a source line with a function call. If there is a breakpoint placed in that function, LLDB will stop there with the `step-over` operation still on the stack.

command, and if, for instance, you decide you don't actually want that outermost
next to continue running, you can remove it with the ``thread plan discard``
command.

Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: Perhaps mention the thread plan logging channel? thread plan list and thread plan discard are obviously more accessible but the logging channel shows the changes to the stack as they occur.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean the step channel? There is a lot of detailed output there, I'm not sure we want the average tutorial.rst reader to be pointed that way...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's a fire-hose for sure, but OTOH, it's the only way to watch the machinery happen. It will be clear right away when you turn it on whether that info is for you or not...

in a function called by the code of the line you are stepping over. Since the step-over
operation remains on the stack, you can examine the state at
the point of the breakpoint hit, step around in that frame, step in to other
frames, hit other breakpoints, etc. Then when you are done, a simple ``continue``
Copy link
Contributor

@felipepiovezan felipepiovezan Sep 27, 2024

Choose a reason for hiding this comment

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

Feel free to push back on this, but I think the big gap between the cause (1) and effect (2) here can be detrimental to the point you are trying to make:

  1. "Since the step-over operation remains on the stack..." and
  2. "when you are done, a simple continue will resume the original step-over...".

Maybe we could remove the "Since" clause (1) and fold it into 2? Something like:

You can examine [...]. When you are done, because the step-over operation remains on the stack, a simple continue...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I thought about that, but if I did it the other way I'm telling you about stepping around without really motivating it are related to what I was just discussing.

Copy link
Contributor

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

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

LGTM! I learned something new reading this!

@jimingham jimingham merged commit a4197e4 into llvm:main Sep 27, 2024
8 checks passed
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
…110167)

This is a convenient little feature of lldb, but if you didn't know it
was there you'd likely never discover it.
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.

6 participants