Skip to content

Commit 8ccd572

Browse files
authored
Merge pull request swiftlang#8869 from medismailben/swift/release/6.0
2 parents ce450e4 + 3bc920e commit 8ccd572

File tree

14 files changed

+167
-60
lines changed

14 files changed

+167
-60
lines changed

lldb/bindings/python/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
109109
FILES
110110
"${LLDB_SOURCE_DIR}/examples/python/templates/parsed_cmd.py"
111111
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py"
112-
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py")
112+
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py"
113+
"${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py")
113114

114115
if(APPLE)
115116
create_python_package(

lldb/examples/python/crashlog.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,9 @@ class DarwinImage(symbolication.Image):
284284
"""Class that represents a binary images in a darwin crash log"""
285285

286286
dsymForUUIDBinary = "/usr/local/bin/dsymForUUID"
287-
if not os.path.exists(dsymForUUIDBinary):
287+
if "LLDB_APPLE_DSYMFORUUID_EXECUTABLE" in os.environ:
288+
dsymForUUIDBinary = os.environ["LLDB_APPLE_DSYMFORUUID_EXECUTABLE"]
289+
elif not os.path.exists(dsymForUUIDBinary):
288290
try:
289291
dsymForUUIDBinary = (
290292
subprocess.check_output("which dsymForUUID", shell=True)
@@ -551,11 +553,15 @@ def load_images(self, options, loaded_images=None):
551553

552554
futures = []
553555
with tempfile.TemporaryDirectory() as obj_dir:
554-
with concurrent.futures.ThreadPoolExecutor() as executor:
555556

556-
def add_module(image, target, obj_dir):
557-
return image, image.add_module(target, obj_dir)
557+
def add_module(image, target, obj_dir):
558+
return image, image.add_module(target, obj_dir)
558559

560+
max_worker = None
561+
if options.no_parallel_image_loading:
562+
max_worker = 1
563+
564+
with concurrent.futures.ThreadPoolExecutor(max_worker) as executor:
559565
for image in images_to_load:
560566
if image not in loaded_images:
561567
if image.uuid == uuid.UUID(int=0):
@@ -1524,6 +1530,7 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
15241530
"file_path": crashlog_path,
15251531
"load_all_images": options.load_all_images,
15261532
"crashed_only": options.crashed_only,
1533+
"no_parallel_image_loading": options.no_parallel_image_loading,
15271534
}
15281535
)
15291536
)
@@ -1716,6 +1723,13 @@ def CreateSymbolicateCrashLogOptions(
17161723
help="show source for all threads, not just the crashed thread",
17171724
default=False,
17181725
)
1726+
arg_parser.add_argument(
1727+
"--no-parallel-image-loading",
1728+
dest="no_parallel_image_loading",
1729+
action="store_true",
1730+
help=argparse.SUPPRESS,
1731+
default=False,
1732+
)
17191733
if add_interactive_options:
17201734
arg_parser.add_argument(
17211735
"-i",
@@ -1794,6 +1808,9 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
17941808
)
17951809
)
17961810

1811+
if "NO_PARALLEL_IMG_LOADING" in os.environ:
1812+
options.no_parallel_image_loading = True
1813+
17971814
if options.version:
17981815
print(debugger.GetVersionString())
17991816
return

lldb/examples/python/crashlog_scripted_process.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def set_crashlog(self, crashlog):
5353
class CrashLogOptions:
5454
load_all_images = False
5555
crashed_only = True
56+
no_parallel_image_loading = False
5657

5758
def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData):
5859
super().__init__(exe_ctx, args)
@@ -84,6 +85,13 @@ def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData
8485
if crashed_only.GetType() == lldb.eStructuredDataTypeBoolean:
8586
self.options.crashed_only = crashed_only.GetBooleanValue()
8687

88+
no_parallel_image_loading = args.GetValueForKey("no_parallel_image_loading")
89+
if no_parallel_image_loading and no_parallel_image_loading.IsValid():
90+
if no_parallel_image_loading.GetType() == lldb.eStructuredDataTypeBoolean:
91+
self.options.no_parallel_image_loading = (
92+
no_parallel_image_loading.GetBooleanValue()
93+
)
94+
8795
self.pid = super().get_process_id()
8896
self.crashed_thread_idx = 0
8997
self.exception = None
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from abc import abstractmethod
2+
3+
import lldb
4+
import struct
5+
6+
from lldb.plugins.scripted_process import ScriptedThread
7+
8+
9+
class OperatingSystem(ScriptedThread):
10+
"""
11+
Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class.
12+
13+
```
14+
thread_info = {
15+
"tid": tid,
16+
"name": "four",
17+
"queue": "queue4",
18+
"state": "stopped",
19+
"stop_reason": "none",
20+
"core" : 2
21+
}
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

lldb/examples/python/templates/scripted_process.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,16 @@ class ScriptedThread(metaclass=ABCMeta):
244244
"""
245245

246246
@abstractmethod
247-
def __init__(self, scripted_process, args):
247+
def __init__(self, process, args):
248248
"""Construct a scripted thread.
249249
250250
Args:
251-
process (ScriptedProcess): The scripted process owning this thread.
251+
process (ScriptedProcess/lldb.SBProcess): The process owning this thread.
252252
args (lldb.SBStructuredData): A Dictionary holding arbitrary
253253
key/value pairs used by the scripted thread.
254254
"""
255255
self.target = None
256-
self.scripted_process = None
256+
self.originating_process = None
257257
self.process = None
258258
self.args = None
259259
self.idx = 0
@@ -268,9 +268,13 @@ def __init__(self, scripted_process, args):
268268
self.frames = []
269269
self.extended_info = []
270270

271-
if isinstance(scripted_process, ScriptedProcess):
272-
self.target = scripted_process.target
273-
self.scripted_process = scripted_process
271+
if (
272+
isinstance(process, ScriptedProcess)
273+
or isinstance(process, lldb.SBProcess)
274+
and process.IsValid()
275+
):
276+
self.target = process.target
277+
self.originating_process = process
274278
self.process = self.target.GetProcess()
275279
self.get_register_info()
276280

@@ -354,14 +358,14 @@ def get_stackframes(self):
354358
def get_register_info(self):
355359
if self.register_info is None:
356360
self.register_info = dict()
357-
if self.scripted_process.arch == "x86_64":
361+
if self.originating_process.arch == "x86_64":
358362
self.register_info["sets"] = ["General Purpose Registers"]
359363
self.register_info["registers"] = INTEL64_GPR
360-
elif "arm64" in self.scripted_process.arch:
364+
elif "arm64" in self.originating_process.arch:
361365
self.register_info["sets"] = ["General Purpose Registers"]
362366
self.register_info["registers"] = ARM64_GPR
363367
else:
364-
raise ValueError("Unknown architecture", self.scripted_process.arch)
368+
raise ValueError("Unknown architecture", self.originating_process.arch)
365369
return self.register_info
366370

367371
@abstractmethod
@@ -505,12 +509,12 @@ def get_stop_reason(self):
505509

506510
# TODO: Passthrough stop reason from driving process
507511
if self.driving_thread.GetStopReason() != lldb.eStopReasonNone:
508-
if "arm64" in self.scripted_process.arch:
512+
if "arm64" in self.originating_process.arch:
509513
stop_reason["type"] = lldb.eStopReasonException
510514
stop_reason["data"][
511515
"desc"
512516
] = self.driving_thread.GetStopDescription(100)
513-
elif self.scripted_process.arch == "x86_64":
517+
elif self.originating_process.arch == "x86_64":
514518
stop_reason["type"] = lldb.eStopReasonSignal
515519
stop_reason["data"]["signal"] = signal.SIGTRAP
516520
else:

lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) {
9292

9393
Target &target = *exe_ctx.GetTargetPtr();
9494
Process &process = *exe_ctx.GetProcessPtr();
95-
ABISP abi_sp = process.GetABI();
9695
const ArchSpec &arch = target.GetArchitecture();
97-
assert(abi_sp && "Missing ABI info");
9896

9997
// Check for a ptrauth-enabled target.
10098
const bool ptrauth_enabled_target =
@@ -110,6 +108,9 @@ bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) {
110108
strm.Printf("Note: Possible pointer authentication failure detected.\n");
111109
};
112110

111+
ABISP abi_sp = process.GetABI();
112+
assert(abi_sp && "Missing ABI info");
113+
113114
// Check if we have a "brk 0xc47x" trap, where the value that failed to
114115
// authenticate is in x16.
115116
Address current_address = current_frame->GetFrameCodeAddress();

lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
1-
#!/usr/bin/env python
2-
31
import lldb
42
import struct
53

4+
from lldb.plugins.operating_system import OperatingSystem
5+
66

7-
class OperatingSystemPlugIn(object):
7+
class OperatingSystemPlugIn(OperatingSystem):
88
"""Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
99

1010
def __init__(self, process):
11-
"""Initialization needs a valid.SBProcess object.
12-
13-
This plug-in will get created after a live process is valid and has stopped for the
14-
first time."""
15-
self.process = None
16-
self.registers = None
17-
self.threads = None
18-
if isinstance(process, lldb.SBProcess) and process.IsValid():
19-
self.process = process
20-
self.threads = None # Will be an dictionary containing info for each thread
21-
22-
def get_target(self):
23-
# NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
24-
# tracks the current target in the LLDB command interpreter which isn't the
25-
# correct thing to use for this plug-in.
26-
return self.process.target
11+
super().__init__(process)
2712

2813
def create_thread(self, tid, context):
2914
if tid == 0x444444444:
@@ -40,23 +25,6 @@ def create_thread(self, tid, context):
4025

4126
def get_thread_info(self):
4227
if not self.threads:
43-
# The sample dictionary below shows the values that can be returned for a thread
44-
# tid => thread ID (mandatory)
45-
# name => thread name (optional key/value pair)
46-
# queue => thread dispatch queue name (optional key/value pair)
47-
# state => thred state (mandatory, set to 'stopped' for now)
48-
# stop_reason => thread stop reason. (mandatory, usually set to 'none')
49-
# Possible values include:
50-
# 'breakpoint' if the thread is stopped at a breakpoint
51-
# 'none' thread is just stopped because the process is stopped
52-
# 'trace' the thread just single stepped
53-
# The usual value for this while threads are in memory is 'none'
54-
# register_data_addr => the address of the register data in memory (optional key/value pair)
55-
# Specifying this key/value pair for a thread will avoid a call to get_register_data()
56-
# and can be used when your registers are in a thread context structure that is contiguous
57-
# in memory. Don't specify this if your register layout in memory doesn't match the layout
58-
# described by the dictionary returned from a call to the
59-
# get_register_info() method.
6028
self.threads = [
6129
{
6230
"tid": 0x111111111,

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: python, native && target-aarch64 && system-darwin
1+
# REQUIRES: python, native && system-darwin
22

33
# RUN: mkdir -p %t.dir
44
# RUN: yaml2obj %S/Inputs/application_specific_info/asi.yaml > %t.dir/asi

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_invalid_target.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: python, native && target-aarch64 && system-darwin
1+
# REQUIRES: python, native && system-darwin
22

33
# RUN: %lldb -o 'command script import lldb.macosx.crashlog' \
44
# RUN: -o 'crashlog -V' \

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: python, native && target-aarch64 && system-darwin
1+
# REQUIRES: python, native && system-darwin
22

33
# RUN: mkdir -p %t.dir
44
# RUN: yaml2obj %S/Inputs/interactive_crashlog/multithread-test.yaml > %t.dir/multithread-test

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: python, native && target-aarch64 && system-darwin
1+
# REQUIRES: python, native && system-darwin
22

33
# RUN: mkdir -p %t.dir
44
# RUN: yaml2obj %S/Inputs/interactive_crashlog/multithread-test.yaml > %t.dir/multithread-test

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: python, native && target-aarch64 && system-darwin
1+
# REQUIRES: python, native && system-darwin
22

33
# RUN: mkdir -p %t.dir
44
# RUN: yaml2obj %S/Inputs/application_specific_info/asi.yaml > %t.dir/asi

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/lit.local.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@ if 'system-darwin' not in config.available_features:
33

44
if 'lldb-repro' in config.available_features:
55
config.unsupported = True
6+
7+
config.environment["LLDB_APPLE_DSYMFORUUID_EXECUTABLE"] = ""
8+
9+
# Temporary parallel image loading deadlock workaround
10+
config.environment["NO_PARALLEL_IMG_LOADING"] = ""

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: python, native && target-aarch64 && system-darwin
1+
# REQUIRES: python, native && system-darwin
22

33
# RUN: mkdir -p %t.dir
44
# RUN: yaml2obj %S/Inputs/interactive_crashlog/multithread-test.yaml > %t.dir/multithread-test

0 commit comments

Comments
 (0)