aboutsummaryrefslogtreecommitdiff
path: root/lldb/test/API/functionalities/scripted_process
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/test/API/functionalities/scripted_process
parent78fbca4a33350571fa409c938722daa84a011e0a (diff)
downloadllvm-84b56202fbe150e06f92c855107489e08cc17bcd.tar.gz
llvm-84b56202fbe150e06f92c855107489e08cc17bcd.tar.bz2
llvm-84b56202fbe150e06f92c855107489e08cc17bcd.zip
[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/test/API/functionalities/scripted_process')
-rw-r--r--lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py65
1 files changed, 64 insertions, 1 deletions
diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
index 2721d961bcb9..835267221ddb 100644
--- a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
+++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
@@ -5,6 +5,7 @@ from typing import Any, Dict
import lldb
from lldb.plugins.scripted_process import ScriptedProcess
from lldb.plugins.scripted_process import ScriptedThread
+from lldb.plugins.scripted_process import ScriptedFrame
class DummyStopHook:
@@ -22,7 +23,7 @@ class DummyScriptedProcess(ScriptedProcess):
def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData):
super().__init__(exe_ctx, args)
- self.threads[0] = DummyScriptedThread(self, None)
+ self.threads[0] = DummyScriptedThread(self, args)
self.memory = {}
addr = 0x500000000
debugger = self.target.GetDebugger()
@@ -69,6 +70,9 @@ class DummyScriptedThread(ScriptedThread):
def __init__(self, process, args):
super().__init__(process, args)
self.frames.append({"pc": 0x0100001B00})
+ self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "baz123"))
+ self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "bar"))
+ self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "foo"))
def get_thread_id(self) -> int:
return 0x19
@@ -109,6 +113,65 @@ class DummyScriptedThread(ScriptedThread):
)
+class DummyScriptedFrame(ScriptedFrame):
+ def __init__(self, thread, args, id, name, sym_ctx=None):
+ super().__init__(thread, args)
+ self.id = id
+ self.name = name
+ self.sym_ctx = sym_ctx
+
+ def get_id(self):
+ return self.id
+
+ def get_function_name(self):
+ return self.name
+
+ def get_register_context(self) -> str:
+ return struct.pack(
+ "21Q",
+ 0x10001,
+ 0x10002,
+ 0x10003,
+ 0x10004,
+ 0x10005,
+ 0x10006,
+ 0x10007,
+ 0x10008,
+ 0x10009,
+ 0x100010,
+ 0x100011,
+ 0x100012,
+ 0x100013,
+ 0x100014,
+ 0x100015,
+ 0x100016,
+ 0x100017,
+ 0x100018,
+ 0x100019,
+ 0x100020,
+ 0x100021,
+ )
+
+ def get_symbol_context(self):
+ def get_symbol_context_for_function(func_name):
+ module = self.target.FindModule(self.target.GetExecutable())
+ if not module.IsValid():
+ return None
+
+ sym_ctx_list = module.FindFunctions(func_name)
+ if not sym_ctx_list.IsValid() or sym_ctx_list.GetSize() == 0:
+ return None
+
+ return sym_ctx_list.GetContextAtIndex(0)
+
+ return (
+ self.sym_ctx if self.sym_ctx else get_symbol_context_for_function(self.name)
+ )
+
+ def get_scripted_frame_plugin(self):
+ return DummyScriptedFrame.__module__ + "." + DummyScriptedFrame.__name__
+
+
def __lldb_init_module(debugger, dict):
# This is used when loading the script in an interactive debug session to
# automatically, register the stop-hook and launch the scripted process.