This revision was automatically updated to reflect the committed changes.
Closed by commit rGec456ba9ca0a: [lldb] Add OperatingSystem base class to the
lldb python module (authored by mib).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D159315/new/
https://reviews.llvm.org/D159315
Files:
lldb/bindings/python/CMakeLists.txt
lldb/examples/python/templates/operating_system.py
lldb/examples/python/templates/scripted_process.py
lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
Index: lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
===================================================================
--- lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
+++ lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
@@ -1,29 +1,14 @@
-#!/usr/bin/env python
-
import lldb
import struct
+from lldb.plugins.operating_system import OperatingSystem
+
-class OperatingSystemPlugIn(object):
+class OperatingSystemPlugIn(OperatingSystem):
"""Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
def __init__(self, process):
- """Initialization needs a valid.SBProcess object.
-
- This plug-in will get created after a live process is valid and has stopped for the
- first time."""
- self.process = None
- self.registers = None
- self.threads = None
- if isinstance(process, lldb.SBProcess) and process.IsValid():
- self.process = process
- self.threads = None # Will be an dictionary containing info for each thread
-
- def get_target(self):
- # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
- # tracks the current target in the LLDB command interpreter which isn't the
- # correct thing to use for this plug-in.
- return self.process.target
+ super().__init__(process)
def create_thread(self, tid, context):
if tid == 0x444444444:
@@ -40,23 +25,6 @@
def get_thread_info(self):
if not self.threads:
- # The sample dictionary below shows the values that can be returned for a thread
- # tid => thread ID (mandatory)
- # name => thread name (optional key/value pair)
- # queue => thread dispatch queue name (optional key/value pair)
- # state => thred state (mandatory, set to 'stopped' for now)
- # stop_reason => thread stop reason. (mandatory, usually set to 'none')
- # Possible values include:
- # 'breakpoint' if the thread is stopped at a breakpoint
- # 'none' thread is just stopped because the process is stopped
- # 'trace' the thread just single stepped
- # 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.
self.threads = [
{
"tid": 0x111111111,
Index: lldb/examples/python/templates/scripted_process.py
===================================================================
--- lldb/examples/python/templates/scripted_process.py
+++ lldb/examples/python/templates/scripted_process.py
@@ -244,16 +244,16 @@
"""
@abstractmethod
- def __init__(self, scripted_process, args):
+ def __init__(self, process, args):
"""Construct a scripted thread.
Args:
- process (ScriptedProcess): The scripted process owning this thread.
+ process (ScriptedProcess/lldb.SBProcess): The process owning this thread.
args (lldb.SBStructuredData): A Dictionary holding arbitrary
key/value pairs used by the scripted thread.
"""
self.target = None
- self.scripted_process = None
+ self.originating_process = None
self.process = None
self.args = None
self.idx = 0
@@ -268,9 +268,13 @@
self.frames = []
self.extended_info = []
- if isinstance(scripted_process, ScriptedProcess):
- self.target = scripted_process.target
- self.scripted_process = scripted_process
+ if (
+ isinstance(process, ScriptedProcess)
+ or isinstance(process, lldb.SBProcess)
+ and process.IsValid()
+ ):
+ self.target = process.target
+ self.originating_process = process
self.process = self.target.GetProcess()
self.get_register_info()
@@ -354,14 +358,14 @@
def get_register_info(self):
if self.register_info is None:
self.register_info = dict()
- if self.scripted_process.arch == "x86_64":
+ if self.originating_process.arch == "x86_64":
self.register_info["sets"] = ["General Purpose Registers"]
self.register_info["registers"] = INTEL64_GPR
- elif "arm64" in self.scripted_process.arch:
+ elif "arm64" in self.originating_process.arch:
self.register_info["sets"] = ["General Purpose Registers"]
self.register_info["registers"] = ARM64_GPR
else:
- raise ValueError("Unknown architecture", self.scripted_process.arch)
+ raise ValueError("Unknown architecture", self.originating_process.arch)
return self.register_info
@abstractmethod
@@ -505,12 +509,12 @@
# TODO: Passthrough stop reason from driving process
if self.driving_thread.GetStopReason() != lldb.eStopReasonNone:
- if "arm64" in self.scripted_process.arch:
+ if "arm64" in self.originating_process.arch:
stop_reason["type"] = lldb.eStopReasonException
stop_reason["data"][
"desc"
] = self.driving_thread.GetStopDescription(100)
- elif self.scripted_process.arch == "x86_64":
+ elif self.originating_process.arch == "x86_64":
stop_reason["type"] = lldb.eStopReasonSignal
stop_reason["data"]["signal"] = signal.SIGTRAP
else:
Index: lldb/examples/python/templates/operating_system.py
===================================================================
--- /dev/null
+++ lldb/examples/python/templates/operating_system.py
@@ -0,0 +1,103 @@
+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
Index: lldb/bindings/python/CMakeLists.txt
===================================================================
--- lldb/bindings/python/CMakeLists.txt
+++ lldb/bindings/python/CMakeLists.txt
@@ -104,7 +104,8 @@
"plugins"
FILES
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py"
- "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py")
+ "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py"
+ "${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py")
if(APPLE)
create_python_package(
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits