summaryrefslogtreecommitdiff
path: root/lldb/examples/python
diff options
context:
space:
mode:
authorMed Ismail Bennani <ismail@bennani.ma>2025-09-04 15:07:11 -0700
committerGitHub <noreply@github.com>2025-09-04 15:07:11 -0700
commit84b56202fbe150e06f92c855107489e08cc17bcd (patch)
tree2f5e9b18cd04740e758ae89d5f4cd9692d8b9b7c /lldb/examples/python
parent78fbca4a33350571fa409c938722daa84a011e0a (diff)
[lldb] Introduce ScriptedFrame affordance (#149622)
This patch introduces a new scripting affordance in lldb: `ScriptedFrame`. This allows user to produce mock stackframes in scripted threads and scripted processes from a python script. With this change, StackFrame can be synthetized from different sources: - Either from a dictionary containing a load address, and a frame index, which is the legacy way. - Or by creating a ScriptedFrame python object. One particularity of synthezising stackframes from the ScriptedFrame python object, is that these frame have an optional PC, meaning that they don't have a report a valid PC and they can act as shells that just contain static information, like the frame function name, the list of variables or registers, etc. It can also provide a symbol context. rdar://157260006 Signed-off-by: Med Ismail Bennani <ismail@bennani.ma> Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Diffstat (limited to 'lldb/examples/python')
-rw-r--r--lldb/examples/python/templates/scripted_process.py136
1 files changed, 136 insertions, 0 deletions
diff --git a/lldb/examples/python/templates/scripted_process.py b/lldb/examples/python/templates/scripted_process.py
index b6360b851907..49059d533f38 100644
--- a/lldb/examples/python/templates/scripted_process.py
+++ b/lldb/examples/python/templates/scripted_process.py
@@ -383,6 +383,142 @@ class ScriptedThread(metaclass=ABCMeta):
"""
return self.extended_info
+ def get_scripted_frame_plugin(self):
+ """Get scripted frame plugin name.
+
+ Returns:
+ str: Name of the scripted frame plugin.
+ """
+ return None
+
+
+class ScriptedFrame(metaclass=ABCMeta):
+ """
+ The base class for a scripted frame.
+
+ Most of the base class methods are `@abstractmethod` that need to be
+ overwritten by the inheriting class.
+ """
+
+ @abstractmethod
+ def __init__(self, thread, args):
+ """Construct a scripted frame.
+
+ Args:
+ thread (ScriptedThread): The thread owning this frame.
+ args (lldb.SBStructuredData): A Dictionary holding arbitrary
+ key/value pairs used by the scripted frame.
+ """
+ self.target = None
+ self.originating_thread = None
+ self.thread = None
+ self.args = None
+ self.id = None
+ self.name = None
+ self.register_info = None
+ self.register_ctx = {}
+ self.variables = []
+
+ if (
+ isinstance(thread, ScriptedThread)
+ or isinstance(thread, lldb.SBThread)
+ and thread.IsValid()
+ ):
+ self.target = thread.target
+ self.process = thread.process
+ self.originating_thread = thread
+ self.thread = self.process.GetThreadByIndexID(thread.tid)
+ self.get_register_info()
+
+ @abstractmethod
+ def get_id(self):
+ """Get the scripted frame identifier.
+
+ Returns:
+ int: The identifier of the scripted frame in the scripted thread.
+ """
+ pass
+
+ def get_pc(self):
+ """Get the scripted frame address.
+
+ Returns:
+ int: The optional address of the scripted frame in the scripted thread.
+ """
+ return None
+
+ def get_symbol_context(self):
+ """Get the scripted frame symbol context.
+
+ Returns:
+ lldb.SBSymbolContext: The symbol context of the scripted frame in the scripted thread.
+ """
+ return None
+
+ def is_inlined(self):
+ """Check if the scripted frame is inlined.
+
+ Returns:
+ bool: True if scripted frame is inlined. False otherwise.
+ """
+ return False
+
+ def is_artificial(self):
+ """Check if the scripted frame is artificial.
+
+ Returns:
+ bool: True if scripted frame is artificial. False otherwise.
+ """
+ return True
+
+ def is_hidden(self):
+ """Check if the scripted frame is hidden.
+
+ Returns:
+ bool: True if scripted frame is hidden. False otherwise.
+ """
+ return False
+
+ def get_function_name(self):
+ """Get the scripted frame function name.
+
+ Returns:
+ str: The function name of the scripted frame.
+ """
+ return self.name
+
+ def get_display_function_name(self):
+ """Get the scripted frame display function name.
+
+ Returns:
+ str: The display function name of the scripted frame.
+ """
+ return self.get_function_name()
+
+ def get_variables(self, filters):
+ """Get the scripted thread state type.
+
+ Args:
+ filter (lldb.SBVariablesOptions): The filter used to resolve the variables
+ Returns:
+ lldb.SBValueList: The SBValueList containing the SBValue for each resolved variable.
+ Returns None by default.
+ """
+ return None
+
+ def get_register_info(self):
+ if self.register_info is None:
+ self.register_info = self.originating_thread.get_register_info()
+ return self.register_info
+
+ @abstractmethod
+ def get_register_context(self):
+ """Get the scripted thread register context
+
+ Returns:
+ str: A byte representing all register's value.
+ """
+ pass
class PassthroughScriptedProcess(ScriptedProcess):
driving_target = None