xref: /llvm-project/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py (revision f732157a9d067e4d300905c831a964222e0eadee)
1import os, struct, signal
2
3from typing import Any, Dict
4
5import lldb
6from lldb.plugins.scripted_process import ScriptedProcess
7from lldb.plugins.scripted_process import ScriptedThread
8
9
10class DummyStopHook:
11    def __init__(self, target, args):
12        self.target = target
13        self.args = args
14
15    def handle_stop(self, exe_ctx, stream):
16        print("My DummyStopHook triggered. Printing args: \n%s" % self.args)
17        sp = exe_ctx.process.GetScriptedImplementation()
18        sp.handled_stop = True
19
20class DummyScriptedProcess(ScriptedProcess):
21    memory = None
22
23    def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData):
24        super().__init__(exe_ctx, args)
25        self.threads[0] = DummyScriptedThread(self, None)
26        self.memory = {}
27        addr = 0x500000000
28        debugger = self.target.GetDebugger()
29        index = debugger.GetIndexOfTarget(self.target)
30        self.memory[addr] = "Hello, target " + str(index)
31        self.handled_stop = False
32
33    def read_memory_at_address(
34        self, addr: int, size: int, error: lldb.SBError
35    ) -> lldb.SBData:
36        data = lldb.SBData().CreateDataFromCString(
37            self.target.GetByteOrder(), self.target.GetCodeByteSize(), self.memory[addr]
38        )
39
40        return data
41
42    def write_memory_at_address(self, addr, data, error):
43        self.memory[addr] = data.GetString(error, 0)
44        return len(self.memory[addr]) + 1
45
46    def get_loaded_images(self):
47        return self.loaded_images
48
49    def get_process_id(self) -> int:
50        return 42
51
52    def should_stop(self) -> bool:
53        return True
54
55    def is_alive(self) -> bool:
56        return True
57
58    def get_scripted_thread_plugin(self):
59        return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__
60
61    def my_super_secret_method(self):
62        if hasattr(self, "my_super_secret_member"):
63            return self.my_super_secret_member
64        else:
65            return None
66
67
68class DummyScriptedThread(ScriptedThread):
69    def __init__(self, process, args):
70        super().__init__(process, args)
71        self.frames.append({"pc": 0x0100001B00})
72
73    def get_thread_id(self) -> int:
74        return 0x19
75
76    def get_name(self) -> str:
77        return DummyScriptedThread.__name__ + ".thread-1"
78
79    def get_state(self) -> int:
80        return lldb.eStateStopped
81
82    def get_stop_reason(self) -> Dict[str, Any]:
83        return {"type": lldb.eStopReasonTrace, "data": {}}
84
85    def get_register_context(self) -> str:
86        return struct.pack(
87            "21Q",
88            1,
89            2,
90            3,
91            4,
92            5,
93            6,
94            7,
95            8,
96            9,
97            10,
98            11,
99            12,
100            13,
101            14,
102            15,
103            16,
104            17,
105            18,
106            19,
107            20,
108            21,
109        )
110
111
112def __lldb_init_module(debugger, dict):
113    # This is used when loading the script in an interactive debug session to
114    # automatically, register the stop-hook and launch the scripted process.
115    if not "SKIP_SCRIPTED_PROCESS_LAUNCH" in os.environ:
116        debugger.HandleCommand(
117            "target stop-hook add -k first -v 1 -k second -v 2 -P %s.%s"
118            % (__name__, DummyStopHook.__name__)
119        )
120        debugger.HandleCommand(
121            "process launch -C %s.%s" % (__name__, DummyScriptedProcess.__name__)
122        )
123    else:
124        print(
125            "Name of the class that will manage the scripted process: '%s.%s'"
126            % (__name__, DummyScriptedProcess.__name__)
127        )
128        print(
129            "Name of the class that will manage the stop-hook: '%s.%s'"
130            % (__name__, DummyStopHook.__name__)
131        )
132