[Lldb-commits] [lldb] 0e90ac9 - Re-revert "[lldb] Move PassthroughScriptedProcess to `lldb.scripted_process` module"
Med Ismail Bennani via lldb-commits
lldb-commits at lists.llvm.org
Thu May 25 14:00:20 PDT 2023
Author: Med Ismail Bennani
Date: 2023-05-25T14:00:11-07:00
New Revision: 0e90ac9c94d716fa78e0c86a6c7f6ff24decf7fe
URL: https://github.com/llvm/llvm-project/commit/0e90ac9c94d716fa78e0c86a6c7f6ff24decf7fe
DIFF: https://github.com/llvm/llvm-project/commit/0e90ac9c94d716fa78e0c86a6c7f6ff24decf7fe.diff
LOG: Re-revert "[lldb] Move PassthroughScriptedProcess to `lldb.scripted_process` module"
This reverts commit 429e74839506ea8ba962d24647264ed81f680bbf since it
didn't address the test failures on GreenDragon.
This patch will mark the tests as expected to fail until I can reproduce
the issue and find a solution.
Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
Added:
Modified:
lldb/examples/python/scripted_process/scripted_process.py
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
Removed:
################################################################################
diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py
index b756cd027866..d74ef02dec85 100644
--- a/lldb/examples/python/scripted_process/scripted_process.py
+++ b/lldb/examples/python/scripted_process/scripted_process.py
@@ -1,6 +1,7 @@
from abc import ABCMeta, abstractmethod
import lldb
+import json, struct, signal
class ScriptedProcess(metaclass=ABCMeta):
@@ -382,6 +383,754 @@ def get_extended_info(self):
return self.extended_info
+class PassthroughScriptedProcess(ScriptedProcess):
+ driving_target = None
+ driving_process = None
+
+ def __init__(self, exe_ctx, args, launched_driving_process=True):
+ super().__init__(exe_ctx, args)
+
+ self.driving_target = None
+ self.driving_process = None
+
+ self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+ if self.driving_target_idx and self.driving_target_idx.IsValid():
+ idx = self.driving_target_idx.GetUnsignedIntegerValue(42)
+ self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+ if launched_driving_process:
+ self.driving_process = self.driving_target.GetProcess()
+ for driving_thread in self.driving_process:
+ structured_data = lldb.SBStructuredData()
+ structured_data.SetFromJSON(
+ json.dumps(
+ {
+ "driving_target_idx": idx,
+ "thread_idx": driving_thread.GetIndexID(),
+ }
+ )
+ )
+
+ self.threads[
+ driving_thread.GetThreadID()
+ ] = PassthroughScriptedThread(self, structured_data)
+
+ for module in self.driving_target.modules:
+ path = module.file.fullpath
+ load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(
+ self.driving_target
+ )
+ self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+ def get_memory_region_containing_address(self, addr):
+ mem_region = lldb.SBMemoryRegionInfo()
+ error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+ if error.Fail():
+ return None
+ return mem_region
+
+ def read_memory_at_address(self, addr, size, error):
+ data = lldb.SBData()
+ bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+ if error.Fail():
+ return data
+
+ data.SetDataWithOwnership(
+ error,
+ bytes_read,
+ self.driving_target.GetByteOrder(),
+ self.driving_target.GetAddressByteSize(),
+ )
+
+ return data
+
+ def write_memory_at_address(self, addr, data, error):
+ return self.driving_process.WriteMemory(
+ addr, bytearray(data.uint8.all()), error
+ )
+
+ def get_process_id(self):
+ return self.driving_process.GetProcessID()
+
+ def is_alive(self):
+ return True
+
+ def get_scripted_thread_plugin(self):
+ return f"{PassthroughScriptedThread.__module__}.{PassthroughScriptedThread.__name__}"
+
+
+class PassthroughScriptedThread(ScriptedThread):
+ def __init__(self, process, args):
+ super().__init__(process, args)
+ driving_target_idx = args.GetValueForKey("driving_target_idx")
+ thread_idx = args.GetValueForKey("thread_idx")
+
+ # TODO: Change to Walrus operator (:=) with oneline if assignment
+ # Requires python 3.8
+ val = thread_idx.GetUnsignedIntegerValue()
+ if val is not None:
+ self.idx = val
+
+ self.driving_target = None
+ self.driving_process = None
+ self.driving_thread = None
+
+ # TODO: Change to Walrus operator (:=) with oneline if assignment
+ # Requires python 3.8
+ val = driving_target_idx.GetUnsignedIntegerValue()
+ if val is not None:
+ self.driving_target = self.target.GetDebugger().GetTargetAtIndex(val)
+ self.driving_process = self.driving_target.GetProcess()
+ self.driving_thread = self.driving_process.GetThreadByIndexID(self.idx)
+
+ if self.driving_thread:
+ self.id = self.driving_thread.GetThreadID()
+
+ def get_thread_id(self):
+ return self.id
+
+ def get_name(self):
+ return f"{PassthroughScriptedThread.__name__}.thread-{self.idx}"
+
+ def get_stop_reason(self):
+ stop_reason = {"type": lldb.eStopReasonInvalid, "data": {}}
+
+ if (
+ self.driving_thread
+ and self.driving_thread.IsValid()
+ and self.get_thread_id() == self.driving_thread.GetThreadID()
+ ):
+ stop_reason["type"] = lldb.eStopReasonNone
+
+ # TODO: Passthrough stop reason from driving process
+ if self.driving_thread.GetStopReason() != lldb.eStopReasonNone:
+ if "arm64" in self.scripted_process.arch:
+ stop_reason["type"] = lldb.eStopReasonException
+ stop_reason["data"][
+ "desc"
+ ] = self.driving_thread.GetStopDescription(100)
+ elif self.scripted_process.arch == "x86_64":
+ stop_reason["type"] = lldb.eStopReasonSignal
+ stop_reason["data"]["signal"] = signal.SIGTRAP
+ else:
+ stop_reason["type"] = self.driving_thread.GetStopReason()
+
+ return stop_reason
+
+ def get_register_context(self):
+ if not self.driving_thread or self.driving_thread.GetNumFrames() == 0:
+ return None
+ frame = self.driving_thread.GetFrameAtIndex(0)
+
+ GPRs = None
+ registerSet = frame.registers # Returns an SBValueList.
+ for regs in registerSet:
+ if "general purpose" in regs.name.lower():
+ GPRs = regs
+ break
+
+ if not GPRs:
+ return None
+
+ for reg in GPRs:
+ self.register_ctx[reg.name] = int(reg.value, base=16)
+
+ return struct.pack(f"{len(self.register_ctx)}Q", *self.register_ctx.values())
+
+
+ARM64_GPR = [
+ {
+ "name": "x0",
+ "bitsize": 64,
+ "offset": 0,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 0,
+ "dwarf": 0,
+ "generic": "arg0",
+ "alt-name": "arg0",
+ },
+ {
+ "name": "x1",
+ "bitsize": 64,
+ "offset": 8,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 1,
+ "dwarf": 1,
+ "generic": "arg1",
+ "alt-name": "arg1",
+ },
+ {
+ "name": "x2",
+ "bitsize": 64,
+ "offset": 16,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 2,
+ "dwarf": 2,
+ "generic": "arg2",
+ "alt-name": "arg2",
+ },
+ {
+ "name": "x3",
+ "bitsize": 64,
+ "offset": 24,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 3,
+ "dwarf": 3,
+ "generic": "arg3",
+ "alt-name": "arg3",
+ },
+ {
+ "name": "x4",
+ "bitsize": 64,
+ "offset": 32,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 4,
+ "dwarf": 4,
+ "generic": "arg4",
+ "alt-name": "arg4",
+ },
+ {
+ "name": "x5",
+ "bitsize": 64,
+ "offset": 40,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 5,
+ "dwarf": 5,
+ "generic": "arg5",
+ "alt-name": "arg5",
+ },
+ {
+ "name": "x6",
+ "bitsize": 64,
+ "offset": 48,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 6,
+ "dwarf": 6,
+ "generic": "arg6",
+ "alt-name": "arg6",
+ },
+ {
+ "name": "x7",
+ "bitsize": 64,
+ "offset": 56,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 7,
+ "dwarf": 7,
+ "generic": "arg7",
+ "alt-name": "arg7",
+ },
+ {
+ "name": "x8",
+ "bitsize": 64,
+ "offset": 64,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 8,
+ "dwarf": 8,
+ },
+ {
+ "name": "x9",
+ "bitsize": 64,
+ "offset": 72,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 9,
+ "dwarf": 9,
+ },
+ {
+ "name": "x10",
+ "bitsize": 64,
+ "offset": 80,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 10,
+ "dwarf": 10,
+ },
+ {
+ "name": "x11",
+ "bitsize": 64,
+ "offset": 88,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 11,
+ "dwarf": 11,
+ },
+ {
+ "name": "x12",
+ "bitsize": 64,
+ "offset": 96,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 12,
+ "dwarf": 12,
+ },
+ {
+ "name": "x13",
+ "bitsize": 64,
+ "offset": 104,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 13,
+ "dwarf": 13,
+ },
+ {
+ "name": "x14",
+ "bitsize": 64,
+ "offset": 112,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 14,
+ "dwarf": 14,
+ },
+ {
+ "name": "x15",
+ "bitsize": 64,
+ "offset": 120,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 15,
+ "dwarf": 15,
+ },
+ {
+ "name": "x16",
+ "bitsize": 64,
+ "offset": 128,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 16,
+ "dwarf": 16,
+ },
+ {
+ "name": "x17",
+ "bitsize": 64,
+ "offset": 136,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 17,
+ "dwarf": 17,
+ },
+ {
+ "name": "x18",
+ "bitsize": 64,
+ "offset": 144,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 18,
+ "dwarf": 18,
+ },
+ {
+ "name": "x19",
+ "bitsize": 64,
+ "offset": 152,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 19,
+ "dwarf": 19,
+ },
+ {
+ "name": "x20",
+ "bitsize": 64,
+ "offset": 160,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 20,
+ "dwarf": 20,
+ },
+ {
+ "name": "x21",
+ "bitsize": 64,
+ "offset": 168,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 21,
+ "dwarf": 21,
+ },
+ {
+ "name": "x22",
+ "bitsize": 64,
+ "offset": 176,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 22,
+ "dwarf": 22,
+ },
+ {
+ "name": "x23",
+ "bitsize": 64,
+ "offset": 184,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 23,
+ "dwarf": 23,
+ },
+ {
+ "name": "x24",
+ "bitsize": 64,
+ "offset": 192,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 24,
+ "dwarf": 24,
+ },
+ {
+ "name": "x25",
+ "bitsize": 64,
+ "offset": 200,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 25,
+ "dwarf": 25,
+ },
+ {
+ "name": "x26",
+ "bitsize": 64,
+ "offset": 208,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 26,
+ "dwarf": 26,
+ },
+ {
+ "name": "x27",
+ "bitsize": 64,
+ "offset": 216,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 27,
+ "dwarf": 27,
+ },
+ {
+ "name": "x28",
+ "bitsize": 64,
+ "offset": 224,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 28,
+ "dwarf": 28,
+ },
+ {
+ "name": "x29",
+ "bitsize": 64,
+ "offset": 232,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 29,
+ "dwarf": 29,
+ "generic": "fp",
+ "alt-name": "fp",
+ },
+ {
+ "name": "x30",
+ "bitsize": 64,
+ "offset": 240,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 30,
+ "dwarf": 30,
+ "generic": "lr",
+ "alt-name": "lr",
+ },
+ {
+ "name": "sp",
+ "bitsize": 64,
+ "offset": 248,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 31,
+ "dwarf": 31,
+ "generic": "sp",
+ "alt-name": "sp",
+ },
+ {
+ "name": "pc",
+ "bitsize": 64,
+ "offset": 256,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 32,
+ "dwarf": 32,
+ "generic": "pc",
+ "alt-name": "pc",
+ },
+ {
+ "name": "cpsr",
+ "bitsize": 32,
+ "offset": 264,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 33,
+ "dwarf": 33,
+ },
+]
+
+INTEL64_GPR = [
+ {
+ "name": "rax",
+ "bitsize": 64,
+ "offset": 0,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 0,
+ "dwarf": 0,
+ },
+ {
+ "name": "rbx",
+ "bitsize": 64,
+ "offset": 8,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 3,
+ "dwarf": 3,
+ },
+ {
+ "name": "rcx",
+ "bitsize": 64,
+ "offset": 16,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 2,
+ "dwarf": 2,
+ "generic": "arg4",
+ "alt-name": "arg4",
+ },
+ {
+ "name": "rdx",
+ "bitsize": 64,
+ "offset": 24,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 1,
+ "dwarf": 1,
+ "generic": "arg3",
+ "alt-name": "arg3",
+ },
+ {
+ "name": "rdi",
+ "bitsize": 64,
+ "offset": 32,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 5,
+ "dwarf": 5,
+ "generic": "arg1",
+ "alt-name": "arg1",
+ },
+ {
+ "name": "rsi",
+ "bitsize": 64,
+ "offset": 40,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 4,
+ "dwarf": 4,
+ "generic": "arg2",
+ "alt-name": "arg2",
+ },
+ {
+ "name": "rbp",
+ "bitsize": 64,
+ "offset": 48,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 6,
+ "dwarf": 6,
+ "generic": "fp",
+ "alt-name": "fp",
+ },
+ {
+ "name": "rsp",
+ "bitsize": 64,
+ "offset": 56,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 7,
+ "dwarf": 7,
+ "generic": "sp",
+ "alt-name": "sp",
+ },
+ {
+ "name": "r8",
+ "bitsize": 64,
+ "offset": 64,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 8,
+ "dwarf": 8,
+ "generic": "arg5",
+ "alt-name": "arg5",
+ },
+ {
+ "name": "r9",
+ "bitsize": 64,
+ "offset": 72,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 9,
+ "dwarf": 9,
+ "generic": "arg6",
+ "alt-name": "arg6",
+ },
+ {
+ "name": "r10",
+ "bitsize": 64,
+ "offset": 80,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 10,
+ "dwarf": 10,
+ },
+ {
+ "name": "r11",
+ "bitsize": 64,
+ "offset": 88,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 11,
+ "dwarf": 11,
+ },
+ {
+ "name": "r12",
+ "bitsize": 64,
+ "offset": 96,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 12,
+ "dwarf": 12,
+ },
+ {
+ "name": "r13",
+ "bitsize": 64,
+ "offset": 104,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 13,
+ "dwarf": 13,
+ },
+ {
+ "name": "r14",
+ "bitsize": 64,
+ "offset": 112,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 14,
+ "dwarf": 14,
+ },
+ {
+ "name": "r15",
+ "bitsize": 64,
+ "offset": 120,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 15,
+ "dwarf": 15,
+ },
+ {
+ "name": "rip",
+ "bitsize": 64,
+ "offset": 128,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "gcc": 16,
+ "dwarf": 16,
+ "generic": "pc",
+ "alt-name": "pc",
+ },
+ {
+ "name": "rflags",
+ "bitsize": 64,
+ "offset": 136,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ "generic": "flags",
+ "alt-name": "flags",
+ },
+ {
+ "name": "cs",
+ "bitsize": 64,
+ "offset": 144,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ },
+ {
+ "name": "fs",
+ "bitsize": 64,
+ "offset": 152,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ },
+ {
+ "name": "gs",
+ "bitsize": 64,
+ "offset": 160,
+ "encoding": "uint",
+ "format": "hex",
+ "set": 0,
+ },
+]
+
ARM64_GPR = [
{
"name": "x0",
diff --git a/lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py b/lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
index a1e450534699..491cabcf82c8 100644
--- a/lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
+++ b/lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
@@ -23,6 +23,7 @@ def setUp(self):
self.script_file = self.script_module + ".py"
@skipUnlessDarwin
+ @expectedFailureDarwin
def test_passthrough_launch(self):
"""Test a simple pass-through process launch"""
self.passthrough_launch()
@@ -43,6 +44,7 @@ def test_passthrough_launch(self):
self.assertState(lldb.SBProcess.GetStateFromEvent(event), lldb.eStateStopped)
@skipUnlessDarwin
+ @expectedFailureDarwin
def test_multiplexed_launch(self):
"""Test a multiple interactive scripted process debugging"""
self.passthrough_launch()
diff --git a/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py b/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
index c97909906679..b0013577d2dc 100644
--- a/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
+++ b/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -12,102 +12,11 @@
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 PassthroughScriptedProcess
+from lldb.plugins.scripted_process import PassthroughScriptedThread
-class PassthruScriptedProcess(ScriptedProcess):
- driving_target = None
- driving_process = None
-
- def __init__(
- self,
- exe_ctx: lldb.SBExecutionContext,
- args: lldb.SBStructuredData,
- launched_driving_process: bool = True,
- ):
- super().__init__(exe_ctx, args)
-
- self.driving_target = None
- self.driving_process = None
-
- self.driving_target_idx = args.GetValueForKey("driving_target_idx")
- if self.driving_target_idx and self.driving_target_idx.IsValid():
- if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
- idx = self.driving_target_idx.GetIntegerValue(42)
- if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
- idx = int(self.driving_target_idx.GetStringValue(100))
- self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
-
- if launched_driving_process:
- self.driving_process = self.driving_target.GetProcess()
- for driving_thread in self.driving_process:
- structured_data = lldb.SBStructuredData()
- structured_data.SetFromJSON(
- json.dumps(
- {
- "driving_target_idx": idx,
- "thread_idx": driving_thread.GetIndexID(),
- }
- )
- )
-
- self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(
- self, structured_data
- )
-
- for module in self.driving_target.modules:
- path = module.file.fullpath
- load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(
- self.driving_target
- )
- self.loaded_images.append({"path": path, "load_addr": load_addr})
-
- def get_memory_region_containing_address(
- self, addr: int
- ) -> lldb.SBMemoryRegionInfo:
- mem_region = lldb.SBMemoryRegionInfo()
- error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
- if error.Fail():
- return None
- return mem_region
-
- def read_memory_at_address(
- self, addr: int, size: int, error: lldb.SBError
- ) -> lldb.SBData:
- data = lldb.SBData()
- bytes_read = self.driving_process.ReadMemory(addr, size, error)
-
- if error.Fail():
- return data
-
- data.SetDataWithOwnership(
- error,
- bytes_read,
- self.driving_target.GetByteOrder(),
- self.driving_target.GetAddressByteSize(),
- )
-
- return data
-
- def write_memory_at_address(
- self, addr: int, data: lldb.SBData, error: lldb.SBError
- ) -> int:
- return self.driving_process.WriteMemory(
- addr, bytearray(data.uint8.all()), error
- )
-
- def get_process_id(self) -> int:
- return 42
-
- def is_alive(self) -> bool:
- return True
-
- def get_scripted_thread_plugin(self) -> str:
- return f"{PassthruScriptedThread.__module__}.{PassthruScriptedThread.__name__}"
-
-
-class MultiplexedScriptedProcess(PassthruScriptedProcess):
+class MultiplexedScriptedProcess(PassthroughScriptedProcess):
def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData):
super().__init__(exe_ctx, args)
self.multiplexer = None
@@ -115,11 +24,11 @@ def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData
parity = args.GetValueForKey("parity")
# TODO: Change to Walrus operator (:=) with oneline if assignment
# Requires python 3.8
- val = extract_value_from_structured_data(parity, 0)
+ val = parity.GetUnsignedIntegerValue()
if val is not None:
self.parity = val
- # Turn PassThruScriptedThread into MultiplexedScriptedThread
+ # Turn PassthroughScriptedThread into MultiplexedScriptedThread
for thread in self.threads.values():
thread.__class__ = MultiplexedScriptedThread
@@ -144,7 +53,7 @@ def get_threads_info(self) -> Dict[int, Any]:
if not self.multiplexer:
return super().get_threads_info()
filtered_threads = self.multiplexer.get_threads_info(pid=self.get_process_id())
- # Update the filtered thread class from PassthruScriptedThread to MultiplexedScriptedThread
+ # Update the filtered thread class from PassthroughScriptedThread to MultiplexedScriptedThread
return dict(
map(
lambda pair: (pair[0], MultiplexedScriptedThread(pair[1])),
@@ -161,91 +70,13 @@ def get_scripted_thread_plugin(self) -> str:
return f"{MultiplexedScriptedThread.__module__}.{MultiplexedScriptedThread.__name__}"
-class PassthruScriptedThread(ScriptedThread):
- def __init__(self, process, args):
- super().__init__(process, args)
- driving_target_idx = args.GetValueForKey("driving_target_idx")
- thread_idx = args.GetValueForKey("thread_idx")
-
- # TODO: Change to Walrus operator (:=) with oneline if assignment
- # Requires python 3.8
- val = extract_value_from_structured_data(thread_idx, 0)
- if val is not None:
- self.idx = val
-
- self.driving_target = None
- self.driving_process = None
- self.driving_thread = None
-
- # TODO: Change to Walrus operator (:=) with oneline if assignment
- # Requires python 3.8
- val = extract_value_from_structured_data(driving_target_idx, 42)
- if val is not None:
- self.driving_target = self.target.GetDebugger().GetTargetAtIndex(val)
- self.driving_process = self.driving_target.GetProcess()
- self.driving_thread = self.driving_process.GetThreadByIndexID(self.idx)
-
- if self.driving_thread:
- self.id = self.driving_thread.GetThreadID()
-
- def get_thread_id(self) -> int:
- return self.id
-
- def get_name(self) -> str:
- return f"{PassthruScriptedThread.__name__}.thread-{self.idx}"
-
- def get_stop_reason(self) -> Dict[str, Any]:
- stop_reason = {"type": lldb.eStopReasonInvalid, "data": {}}
-
- if (
- self.driving_thread
- and self.driving_thread.IsValid()
- and self.get_thread_id() == self.driving_thread.GetThreadID()
- ):
- stop_reason["type"] = lldb.eStopReasonNone
-
- if self.driving_thread.GetStopReason() != lldb.eStopReasonNone:
- if "arm64" in self.scripted_process.arch:
- stop_reason["type"] = lldb.eStopReasonException
- stop_reason["data"][
- "desc"
- ] = self.driving_thread.GetStopDescription(100)
- elif self.scripted_process.arch == "x86_64":
- stop_reason["type"] = lldb.eStopReasonSignal
- stop_reason["data"]["signal"] = signal.SIGTRAP
- else:
- stop_reason["type"] = self.driving_thread.GetStopReason()
-
- return stop_reason
-
- def get_register_context(self) -> str:
- if not self.driving_thread or self.driving_thread.GetNumFrames() == 0:
- return None
- frame = self.driving_thread.GetFrameAtIndex(0)
-
- GPRs = None
- registerSet = frame.registers # Returns an SBValueList.
- for regs in registerSet:
- if "general purpose" in regs.name.lower():
- GPRs = regs
- break
-
- if not GPRs:
- return None
-
- for reg in GPRs:
- self.register_ctx[reg.name] = int(reg.value, base=16)
-
- return struct.pack(f"{len(self.register_ctx)}Q", *self.register_ctx.values())
-
-
-class MultiplexedScriptedThread(PassthruScriptedThread):
+class MultiplexedScriptedThread(PassthroughScriptedThread):
def get_name(self) -> str:
parity = "Odd" if self.scripted_process.parity % 2 else "Even"
return f"{parity}{MultiplexedScriptedThread.__name__}.thread-{self.idx}"
-class MultiplexerScriptedProcess(PassthruScriptedProcess):
+class MultiplexerScriptedProcess(PassthroughScriptedProcess):
listener = None
multiplexed_processes = None
@@ -254,9 +85,9 @@ def handle_process_state_event():
# Update multiplexer process
log("Updating interactive scripted process threads")
dbg = self.driving_target.GetDebugger()
- log("Clearing interactive scripted process threads")
- self.threads.clear()
+ new_driving_thread_ids = []
for driving_thread in self.driving_process:
+ new_driving_thread_ids.append(driving_thread.id)
log(f"{len(self.threads)} New thread {hex(driving_thread.id)}")
structured_data = lldb.SBStructuredData()
structured_data.SetFromJSON(
@@ -270,10 +101,17 @@ def handle_process_state_event():
)
)
- self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(
+ self.threads[driving_thread.id] = PassthroughScriptedThread(
self, structured_data
)
+ for thread_id in self.threads:
+ if thread_id not in new_driving_thread_ids:
+ log(f"Removing old thread {hex(thread_id)}")
+ del self.threads[thread_id]
+
+ print(f"New thread count: {len(self.threads)}")
+
mux_process = self.target.GetProcess()
mux_process.ForceScriptedState(lldb.eStateRunning)
mux_process.ForceScriptedState(lldb.eStateStopped)
@@ -284,6 +122,8 @@ def handle_process_state_event():
event = lldb.SBEvent()
while True:
+ if not self.driving_process:
+ continue
if self.listener.WaitForEvent(1, event):
event_mask = event.GetType()
if event_mask & lldb.SBProcess.eBroadcastBitStateChanged:
@@ -475,15 +315,6 @@ def duplicate_target(driving_target):
return debugger.CreateTargetWithFileAndTargetTriple(exe, triple)
-def extract_value_from_structured_data(data, default_val):
- if data and data.IsValid():
- if data.GetType() == lldb.eStructuredDataTypeInteger:
- return data.GetIntegerValue(default_val)
- if data.GetType() == lldb.eStructuredDataTypeString:
- return int(data.GetStringValue(100))
- return default_val
-
-
def create_mux_process(debugger, command, exe_ctx, result, dict):
if not debugger.GetNumTargets() > 0:
return result.SetError(
diff --git a/lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
index 28f8630ba861..6c695c659d50 100644
--- a/lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
+++ b/lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
@@ -35,6 +35,7 @@ def get_module_with_name(self, target, name):
@skipIfOutOfTreeDebugserver
@skipIfRemote
@skipIfAsan # On ASAN builds, this test times-out (rdar://98678134)
+ @expectedFailureDarwin
def test_launch_scripted_process_stack_frames(self):
"""Test that we can launch an lldb scripted process from the command
line, check its process ID and read string from memory."""
More information about the lldb-commits
mailing list