[Lldb-commits] [lldb] [lldb] Introduce ScriptedFrameProvider for real threads (PR #161870)

via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 10 12:14:05 PDT 2025


jimingham wrote:

There are two parts to this project.  One is how to make synthetic stack frames that can be consed up and returned by some kind of scripted stack frame list entity.  The other is how to structure the entity that uses synthetic stack frames to re-present the original StackFrameList of a thread.  I'm mostly commenting on the second part of the design here.  I agree with the other people commenting here that the latter part of the design is trying to help where it doesn't need to and ends up being confusing.

To start with, the StackFrameList is better thought of as a generator of StackFrames that answers "give me stack frame at index N" than something that has a list of all the frames in it.  So instead of thinking about this as a static process of "inserting or replacing frames in a stack frame list" it would be clearer if this design where we're re-presenting extant StackFramesLists from a thread - not creating them from whole cloth like the ScriptedThreads do - if the process were modeled as a sequence of generators that uses some incoming StackFrameList generator as the source for it's reply to "give me stack frame at index N".  So this would look something like:

1) Adding a SyntheticStackFrameList subclass of StackFrameList that is constructed from a source StackFrameList and a StackFrameList transmogrifier where the transmogrifier is something that takes a incoming StackFrameList and uses it and whatever internal logic it wants to implement the answer to "give me stack frame at index N" which is what gets asked of the base StackFrameList.

2) A system in the Thread to hold a chain of StackFrameLists , and on request to produce "stack frame at index N" from any point in this list of transmogrified stack frames.  We might at the start just have one "real" frame and one "transmogrifier" and extend that to a chain of them later, but we should keep the possibility of chaining them in mind.  In either case, we want to support the ability to show users the raw "native" stack frame as well as the cooked one.  So there should be a gesture to ask at various points in the chain.

As an aside, I don't think the notion of an unwinder is the right model.  The unwinder's job is "Given Stack Frame N, produce THE frame one older than it."  But for instance, way back in the day I did a C-Stack to Tcl stack transmogrifier (this was in gdbtk and some 30 years ago...) based on the fact that I could recognize the C stack frame sequence corresponding to one Tcl function invocation (the sequence was 3 or 4 frames long, I can't remember the details now).  So in my transmogrifier, I ran through the incoming C stack and if I saw this pattern of C Frames, I elided them into a single frame that had the Tcl function source, and variables and presented that as a single frame, with all the indexes suitably adjusted for the elision.

So the notion we want here is not an unwinder but a transmogrifier that takes a source stack frame list and produces another StackFrameList, or really "intercepts the request for 'give me frame at index N" and uses its stackframelist StackFrameList to answer the question.

I don't think we need to be more specific about it than that, so I don't for instance see the various insertion modes as useful.  The same transmogrifier might do any of those operations depending on what it sees in the StackFrameList it was given to work on.  Instead, when you ask a thread for the "stack frame at index 5" from a thread, this would just ask the top-most transmogrifier to produce the stack up to frame 5.  We don't need to care how it managed that.

If there are no stack frame provider(s) attached to the thread (or the user did `thread backtrace --raw`), that would just ask the native unwinder based stack frame (or if this was a Scripted Thread, the scripted thread's list) for Frame 5.

If there were a transmogrifier added then it would ask the ScriptedStackFrameList to use its transmogrifier and the StackFrameList it is based off for the requested frame.  That would do whatever it wanted (I don't think we need to get involved with that) and produce frame 5.  This would very naturally chain, since when you added a second ScriptedStackFrameList to the Thread, it would get the first Scripted StackFrameList as its source StackFrameList.



https://github.com/llvm/llvm-project/pull/161870


More information about the lldb-commits mailing list