diff options
| author | Med Ismail Bennani <ismail@bennani.ma> | 2025-09-04 15:07:11 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-04 15:07:11 -0700 |
| commit | 84b56202fbe150e06f92c855107489e08cc17bcd (patch) | |
| tree | 2f5e9b18cd04740e758ae89d5f4cd9692d8b9b7c /lldb/examples/python | |
| parent | 78fbca4a33350571fa409c938722daa84a011e0a (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.py | 136 |
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 |
