Skip to content

Commit 74f34b6

Browse files
authored
Merge pull request #8755 from medismailben/swift/release/6.0
2 parents 4218d86 + e3ec080 commit 74f34b6

File tree

2 files changed

+85
-66
lines changed

2 files changed

+85
-66
lines changed

lldb/examples/python/crashlog.py

Lines changed: 67 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ def add_ident(self, ident):
252252
self.idents.append(ident)
253253

254254
def did_crash(self):
255-
return self.reason is not None
255+
return self.crashed
256256

257257
def __str__(self):
258258
if self.app_specific_backtrace:
@@ -414,9 +414,20 @@ def locate_module_and_debug_symbols(self):
414414
with print_lock:
415415
print('falling back to binary inside "%s"' % dsym)
416416
self.symfile = dsym
417-
for filename in os.listdir(dwarf_dir):
418-
self.path = os.path.join(dwarf_dir, filename)
419-
if self.find_matching_slice():
417+
# Look for the executable next to the dSYM bundle.
418+
parent_dir = os.path.dirname(dsym)
419+
executables = []
420+
for root, _, files in os.walk(parent_dir):
421+
for file in files:
422+
abs_path = os.path.join(root, file)
423+
if os.path.isfile(abs_path) and os.access(
424+
abs_path, os.X_OK
425+
):
426+
executables.append(abs_path)
427+
for binary in executables:
428+
basename = os.path.basename(binary)
429+
if basename == self.identifier:
430+
self.path = binary
420431
found_matching_slice = True
421432
break
422433
if found_matching_slice:
@@ -522,6 +533,49 @@ def create_target(self):
522533
def get_target(self):
523534
return self.target
524535

536+
def load_images(self, options, loaded_images=None):
537+
if not loaded_images:
538+
loaded_images = []
539+
images_to_load = self.images
540+
if options.load_all_images:
541+
for image in self.images:
542+
image.resolve = True
543+
elif options.crashed_only:
544+
for thread in self.threads:
545+
if thread.did_crash():
546+
images_to_load = []
547+
for ident in thread.idents:
548+
for image in self.find_images_with_identifier(ident):
549+
image.resolve = True
550+
images_to_load.append(image)
551+
552+
futures = []
553+
with tempfile.TemporaryDirectory() as obj_dir:
554+
with concurrent.futures.ThreadPoolExecutor() as executor:
555+
556+
def add_module(image, target, obj_dir):
557+
return image, image.add_module(target, obj_dir)
558+
559+
for image in images_to_load:
560+
if image not in loaded_images:
561+
if image.uuid == uuid.UUID(int=0):
562+
continue
563+
futures.append(
564+
executor.submit(
565+
add_module,
566+
image=image,
567+
target=self.target,
568+
obj_dir=obj_dir,
569+
)
570+
)
571+
572+
for future in concurrent.futures.as_completed(futures):
573+
image, err = future.result()
574+
if err:
575+
print(err)
576+
else:
577+
loaded_images.append(image)
578+
525579

526580
class CrashLogFormatException(Exception):
527581
pass
@@ -1404,36 +1458,7 @@ def SymbolicateCrashLog(crash_log, options):
14041458
if not target:
14051459
return
14061460

1407-
if options.load_all_images:
1408-
for image in crash_log.images:
1409-
image.resolve = True
1410-
elif options.crashed_only:
1411-
for thread in crash_log.threads:
1412-
if thread.did_crash():
1413-
for ident in thread.idents:
1414-
for image in crash_log.find_images_with_identifier(ident):
1415-
image.resolve = True
1416-
1417-
futures = []
1418-
loaded_images = []
1419-
with tempfile.TemporaryDirectory() as obj_dir:
1420-
with concurrent.futures.ThreadPoolExecutor() as executor:
1421-
1422-
def add_module(image, target, obj_dir):
1423-
return image, image.add_module(target, obj_dir)
1424-
1425-
for image in crash_log.images:
1426-
futures.append(
1427-
executor.submit(
1428-
add_module, image=image, target=target, obj_dir=obj_dir
1429-
)
1430-
)
1431-
for future in concurrent.futures.as_completed(futures):
1432-
image, err = future.result()
1433-
if err:
1434-
print(err)
1435-
else:
1436-
loaded_images.append(image)
1461+
crash_log.load_images(options)
14371462

14381463
if crash_log.backtraces:
14391464
for thread in crash_log.backtraces:
@@ -1465,6 +1490,7 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
14651490
raise InteractiveCrashLogException(
14661491
"couldn't create target provided by the user (%s)" % options.target_path
14671492
)
1493+
crashlog.target = target
14681494

14691495
# 2. If the user didn't provide a target, try to create a target using the symbolicator
14701496
if not target or not target.IsValid():
@@ -1494,7 +1520,11 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
14941520
structured_data = lldb.SBStructuredData()
14951521
structured_data.SetFromJSON(
14961522
json.dumps(
1497-
{"file_path": crashlog_path, "load_all_images": options.load_all_images}
1523+
{
1524+
"file_path": crashlog_path,
1525+
"load_all_images": options.load_all_images,
1526+
"crashed_only": options.crashed_only,
1527+
}
14981528
)
14991529
)
15001530
launch_info = lldb.SBLaunchInfo(None)
@@ -1627,7 +1657,8 @@ def CreateSymbolicateCrashLogOptions(
16271657
"--no-crashed-only",
16281658
action="store_false",
16291659
dest="crashed_only",
1630-
help="do not symbolicate the crashed thread",
1660+
help="in batch mode, symbolicate all threads, not only the crashed one",
1661+
default=False,
16311662
)
16321663
arg_parser.add_argument(
16331664
"--disasm-depth",

lldb/examples/python/crashlog_scripted_process.py

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,7 @@ def set_crashlog(self, crashlog):
2929
if hasattr(self.crashlog, "asb"):
3030
self.extended_thread_info = self.crashlog.asb
3131

32-
if self.load_all_images:
33-
for image in self.crashlog.images:
34-
image.resolve = True
35-
else:
36-
for thread in self.crashlog.threads:
37-
if thread.did_crash():
38-
for ident in thread.idents:
39-
for image in self.crashlog.find_images_with_identifier(ident):
40-
image.resolve = True
41-
42-
with tempfile.TemporaryDirectory() as obj_dir:
43-
for image in self.crashlog.images:
44-
if image not in self.loaded_images:
45-
if image.uuid == uuid.UUID(int=0):
46-
continue
47-
err = image.add_module(self.target, obj_dir)
48-
if err:
49-
# Append to SBCommandReturnObject
50-
print(err)
51-
else:
52-
self.loaded_images.append(image)
32+
crashlog.load_images(self.options, self.loaded_images)
5333

5434
for thread in self.crashlog.threads:
5535
if (
@@ -70,6 +50,10 @@ def set_crashlog(self, crashlog):
7050
self.app_specific_thread, self.addr_mask, self.target
7151
)
7252

53+
class CrashLogOptions:
54+
load_all_images = False
55+
crashed_only = True
56+
7357
def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData):
7458
super().__init__(exe_ctx, args)
7559

@@ -88,13 +72,17 @@ def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData
8872
# Return error
8973
return
9074

75+
self.options = self.CrashLogOptions()
76+
9177
load_all_images = args.GetValueForKey("load_all_images")
9278
if load_all_images and load_all_images.IsValid():
9379
if load_all_images.GetType() == lldb.eStructuredDataTypeBoolean:
94-
self.load_all_images = load_all_images.GetBooleanValue()
80+
self.options.load_all_images = load_all_images.GetBooleanValue()
9581

96-
if not self.load_all_images:
97-
self.load_all_images = False
82+
crashed_only = args.GetValueForKey("crashed_only")
83+
if crashed_only and crashed_only.IsValid():
84+
if crashed_only.GetType() == lldb.eStructuredDataTypeBoolean:
85+
self.options.crashed_only = crashed_only.GetBooleanValue()
9886

9987
self.pid = super().get_process_id()
10088
self.crashed_thread_idx = 0
@@ -159,14 +147,14 @@ def resolve_stackframes(thread, addr_mask, target):
159147
return frames
160148

161149
def create_stackframes(self):
162-
if not (self.scripted_process.load_all_images or self.has_crashed):
150+
if not (self.originating_process.options.load_all_images or self.has_crashed):
163151
return None
164152

165153
if not self.backing_thread or not len(self.backing_thread.frames):
166154
return None
167155

168156
self.frames = CrashLogScriptedThread.resolve_stackframes(
169-
self.backing_thread, self.scripted_process.addr_mask, self.target
157+
self.backing_thread, self.originating_process.addr_mask, self.target
170158
)
171159

172160
return self.frames
@@ -182,7 +170,7 @@ def __init__(self, process, args, crashlog_thread):
182170
else:
183171
self.name = self.backing_thread.name
184172
self.queue = self.backing_thread.queue
185-
self.has_crashed = self.scripted_process.crashed_thread_idx == self.idx
173+
self.has_crashed = self.originating_process.crashed_thread_idx == self.idx
186174
self.create_stackframes()
187175

188176
def get_state(self):
@@ -195,8 +183,8 @@ def get_stop_reason(self) -> Dict[str, Any]:
195183
return {"type": lldb.eStopReasonNone}
196184
# TODO: Investigate what stop reason should be reported when crashed
197185
stop_reason = {"type": lldb.eStopReasonException, "data": {}}
198-
if self.scripted_process.exception:
199-
stop_reason["data"]["mach_exception"] = self.scripted_process.exception
186+
if self.originating_process.exception:
187+
stop_reason["data"]["mach_exception"] = self.originating_process.exception
200188
return stop_reason
201189

202190
def get_register_context(self) -> str:
@@ -209,5 +197,5 @@ def get_register_context(self) -> str:
209197

210198
def get_extended_info(self):
211199
if self.has_crashed:
212-
self.extended_info = self.scripted_process.extended_thread_info
200+
self.extended_info = self.originating_process.extended_thread_info
213201
return self.extended_info

0 commit comments

Comments
 (0)