xref: /llvm-project/lldb/examples/python/templates/operating_system.py (revision 59f4267c8e0625c6583327be2db1608930f2d796)
1from abc import abstractmethod
2
3import lldb
4import struct
5
6from lldb.plugins.scripted_process import ScriptedThread
7
8
9class OperatingSystem(ScriptedThread):
10    """
11    Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class.
12
13    .. code-block:: python
14
15        thread_info = {
16            "tid": tid,
17            "name": "four",
18            "queue": "queue4",
19            "state": "stopped",
20            "stop_reason": "none",
21            "core" : 2
22        }
23
24    - tid : thread ID (mandatory)
25    - name : thread name (optional key/value pair)
26    - queue : thread dispatch queue name (optional key/value pair)
27    - state : thread state (mandatory, set to 'stopped' for now)
28    - core : the index of the core (lldb) thread that this OS Thread should shadow
29    - stop_reason : thread stop reason. (mandatory, usually set to 'none')
30        Possible values include:
31        - 'breakpoint': thread is stopped at a breakpoint
32        - 'none': thread is stopped because the process is stopped
33        - 'trace': thread is stopped after single stepping
34        The usual value for this while threads are in memory is 'none'
35    - register_data_addr : the address of the register data in memory (optional key/value pair)
36        Specifying this key/value pair for a thread will avoid a call to get_register_data()
37        and can be used when your registers are in a thread context structure that is contiguous
38        in memory. Don't specify this if your register layout in memory doesn't match the layout
39        described by the dictionary returned from a call to the get_register_info() method.
40    """
41
42    def __init__(self, process):
43        """Initialization needs a valid lldb.SBProcess object. This plug-in
44        will get created after a live process is valid and has stopped for the
45        first time.
46
47        Args:
48            process (lldb.SBProcess): The process owning this thread.
49        """
50        self.registers = None
51        super().__init__(process, None)
52        self.registers = self.register_info
53        self.threads = []
54
55    def create_thread(self, tid, context):
56        """Lazily create an operating system thread using a thread information
57        dictionary and an optional operating system thread context address.
58        This method is called manually, using the SBAPI
59        `lldb.SBProcess.CreateOSPluginThread` affordance.
60
61        Args:
62            tid (int): Thread ID to get `thread_info` dictionary for.
63            context (int): Address of the operating system thread struct.
64
65        Returns:
66            Dict: The `thread_info` dictionary containing the various information
67            for lldb to create a Thread object and add it to the process thread list.
68        """
69        return None
70
71    @abstractmethod
72    def get_thread_info(self):
73        """Get the list of operating system threads. This method gets called
74        automatically every time the process stops and it needs to update its
75        thread list.
76
77        Returns:
78            List[thread_info]: A list of `os_thread` dictionaries
79                containing at least for each entry, the thread id, it's name,
80                queue, state, stop reason. It can also contain a
81                `register_data_addr`. The list can be empty.
82        """
83        pass
84
85    @abstractmethod
86    def get_register_data(self, tid):
87        """Get the operating system thread register context for given a thread
88        id. This method is called when unwinding the stack of one of the
89        operating system threads.
90
91        Args:
92            tid (int): Thread ID to get register context for.
93
94        Returns:
95            str: A byte representing all register's value.
96        """
97        pass
98
99    def get_register_context(self):
100        pass
101
102    def get_stop_reason(self):
103        pass
104