103 lines
3.7 KiB
Python
103 lines
3.7 KiB
Python
from abc import abstractmethod
|
|
|
|
import lldb
|
|
import struct
|
|
|
|
from lldb.plugins.scripted_process import ScriptedThread
|
|
|
|
|
|
class OperatingSystem(ScriptedThread):
|
|
"""
|
|
Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class.
|
|
|
|
```
|
|
thread_info = {
|
|
"tid": tid,
|
|
"name": "four",
|
|
"queue": "queue4",
|
|
"state": "stopped",
|
|
"stop_reason": "none",
|
|
"core" : 2
|
|
}
|
|
```
|
|
|
|
- tid : thread ID (mandatory)
|
|
- name : thread name (optional key/value pair)
|
|
- queue : thread dispatch queue name (optional key/value pair)
|
|
- state : thread state (mandatory, set to 'stopped' for now)
|
|
- core : the index of the core (lldb) thread that this OS Thread should shadow
|
|
- stop_reason : thread stop reason. (mandatory, usually set to 'none')
|
|
Possible values include:
|
|
- 'breakpoint': thread is stopped at a breakpoint
|
|
- 'none': thread is stopped because the process is stopped
|
|
- 'trace': thread is stopped after single stepping
|
|
The usual value for this while threads are in memory is 'none'
|
|
- register_data_addr : the address of the register data in memory (optional key/value pair)
|
|
Specifying this key/value pair for a thread will avoid a call to get_register_data()
|
|
and can be used when your registers are in a thread context structure that is contiguous
|
|
in memory. Don't specify this if your register layout in memory doesn't match the layout
|
|
described by the dictionary returned from a call to the get_register_info() method.
|
|
"""
|
|
|
|
def __init__(self, process):
|
|
"""Initialization needs a valid lldb.SBProcess object. This plug-in
|
|
will get created after a live process is valid and has stopped for the
|
|
first time.
|
|
|
|
Args:
|
|
process (lldb.SBProcess): The process owning this thread.
|
|
"""
|
|
self.registers = None
|
|
super().__init__(process, None)
|
|
self.registers = self.register_info
|
|
self.threads = []
|
|
|
|
def create_thread(self, tid, context):
|
|
"""Lazily create an operating system thread using a thread information
|
|
dictionary and an optional operating system thread context address.
|
|
This method is called manually, using the SBAPI
|
|
`lldb.SBProcess.CreateOSPluginThread` affordance.
|
|
|
|
Args:
|
|
tid (int): Thread ID to get `thread_info` dictionary for.
|
|
context (int): Address of the operating system thread struct.
|
|
|
|
Returns:
|
|
Dict: The `thread_info` dictionary containing the various information
|
|
for lldb to create a Thread object and add it to the process thread list.
|
|
"""
|
|
return None
|
|
|
|
@abstractmethod
|
|
def get_thread_info(self):
|
|
"""Get the list of operating system threads. This method gets called
|
|
automatically every time the process stops and it needs to update its
|
|
thread list.
|
|
|
|
Returns:
|
|
List[thread_info]: A list of `os_thread` dictionaries
|
|
containing at least for each entry, the thread id, it's name,
|
|
queue, state, stop reason. It can also contain a
|
|
`register_data_addr`. The list can be empty.
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_register_data(self, tid):
|
|
"""Get the operating system thread register context for given a thread
|
|
id. This method is called when unwinding the stack of one of the
|
|
operating system threads.
|
|
|
|
Args:
|
|
tid (int): Thread ID to get register context for.
|
|
|
|
Returns:
|
|
str: A byte representing all register's value.
|
|
"""
|
|
pass
|
|
|
|
def get_register_context(self):
|
|
pass
|
|
|
|
def get_stop_reason(self):
|
|
pass
|