[Lldb-commits] [lldb] [lldb][doc] Improve documentation for `ScriptedFrameProvider` (PR #179996)

Adrian Vogelsgesang via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 5 13:48:51 PST 2026


https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/179996

>From 883280ef441136bf9c32bac887289d5d021ccae3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Thu, 5 Feb 2026 15:06:30 +0000
Subject: [PATCH 1/2] [lldb][doc] Improve documentation for
 `ScriptedFrameProvider`

---
 .../templates/scripted_frame_provider.py      | 40 ++++++++++++++++---
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/lldb/examples/python/templates/scripted_frame_provider.py b/lldb/examples/python/templates/scripted_frame_provider.py
index a45ef9427a532..e5a7650b238f2 100644
--- a/lldb/examples/python/templates/scripted_frame_provider.py
+++ b/lldb/examples/python/templates/scripted_frame_provider.py
@@ -19,16 +19,41 @@ class ScriptedFrameProvider(metaclass=ABCMeta):
     Most of the base class methods are `@abstractmethod` that need to be
     overwritten by the inheriting class.
 
+    The constructor of this class sets up the following attributes:
+
+    - ``input_frames`` (lldb.SBFrameList or None): The frame list to use as input
+    - ``thread`` (lldb.SBThread or None): The thread this provider is attached to.
+    - ``target`` (lldb.SBTarget or None): The target from the thread's process.
+    - ``process`` (lldb.SBProcess or None): The process that owns the thread.
+    - ``args`` (lldb.SBStructuredData or None): Dictionary-like structured data passed when the provider was registered.
+
     Example usage:
 
     .. code-block:: python
 
-        # Attach a frame provider to a thread
-        thread = process.GetSelectedThread()
-        error = thread.SetScriptedFrameProvider(
-                        "my_module.MyFrameProvider",
-                        lldb.SBStructuredData()
-        )
+        import lldb
+        from lldb.plugins.scripted_frame_provider import ScriptedFrameProvider
+
+        class CoroFrameProvider(ScriptedFrameProvider):
+            def __init__(self, input_frames, args):
+                super().__init__(input_frames, args)
+
+            @staticmethod
+            def get_description():
+                return "C++ coroutine frame unwinding"
+
+            def get_frame_at_index(self, index):
+                # Duplicate every frame
+                return int(index / 2)
+
+        def __lldb_init_module(debugger, internal_dict):
+            debugger.HandleCommand(f"target frame-provider register -C {__name__}.CoroFrameProvider")
+
+        if __name__ == '__main__':
+            print("This script should be loaded from LLDB using `command script import <filename>`")
+
+    You can register your frame provider either via the CLI command ``target frame-provider register`` or
+    via the API ``SBThread.RegisterScriptedFrameProvider``.
     """
 
     @staticmethod
@@ -74,6 +99,7 @@ def get_description():
 
         .. code-block:: python
 
+            @staticmethod
             def get_description(self):
                 return "Crash log frame provider for thread 1"
         """
@@ -150,10 +176,12 @@ def get_frame_at_index(self, index):
                 if no frame exists at this index. The dictionary should contain:
 
             Required fields:
+
             - idx (int): The synthetic frame index (0 for youngest/top frame)
             - pc (int): The program counter address for the synthetic frame
 
             Alternatively, you can return:
+
             - A ScriptedFrame object for full control over frame behavior
             - An integer representing an input frame index to reuse
             - None to indicate no more frames exist

>From 5775ce771d7695d5c72fb1402b0145c6c7589095 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Thu, 5 Feb 2026 21:48:19 +0000
Subject: [PATCH 2/2] Adjust docs of return value of `get_frame_at_index`

---
 .../templates/scripted_frame_provider.py      | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lldb/examples/python/templates/scripted_frame_provider.py b/lldb/examples/python/templates/scripted_frame_provider.py
index e5a7650b238f2..b70009aab1e97 100644
--- a/lldb/examples/python/templates/scripted_frame_provider.py
+++ b/lldb/examples/python/templates/scripted_frame_provider.py
@@ -172,19 +172,20 @@ def get_frame_at_index(self, index):
             index (int): The frame index to retrieve (0 for youngest/top frame).
 
         Returns:
-            Dict or None: A frame dictionary describing the stack frame, or None
-                if no frame exists at this index. The dictionary should contain:
+            ScriptedFrame, integer, Dict or None: An object describing the stack
+               stack frame, or None if no frame exists at this index.
 
-            Required fields:
+            An integer represents the corresponding input frame index to reuse,
+            in case you want to just forward an frame from the ``input_frames``.
 
-            - idx (int): The synthetic frame index (0 for youngest/top frame)
-            - pc (int): The program counter address for the synthetic frame
+            Returning a ScriptedFrame object injects artificial frames giving
+            you full control over the frame behavior.
 
-            Alternatively, you can return:
+            Returning a dictionary also injects an artificial frame, but with
+            less control over the frame behavior. The dictionary must contain:
 
-            - A ScriptedFrame object for full control over frame behavior
-            - An integer representing an input frame index to reuse
-            - None to indicate no more frames exist
+            - idx (int): The synthetic frame index (0 for youngest/top frame)
+            - pc (int): The program counter address for the synthetic frame
 
         Example:
 



More information about the lldb-commits mailing list