@@ -252,7 +252,7 @@ def add_ident(self, ident):
252
252
self .idents .append (ident )
253
253
254
254
def did_crash (self ):
255
- return self .reason is not None
255
+ return self .crashed
256
256
257
257
def __str__ (self ):
258
258
if self .app_specific_backtrace :
@@ -414,9 +414,20 @@ def locate_module_and_debug_symbols(self):
414
414
with print_lock :
415
415
print ('falling back to binary inside "%s"' % dsym )
416
416
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
420
431
found_matching_slice = True
421
432
break
422
433
if found_matching_slice :
@@ -522,6 +533,49 @@ def create_target(self):
522
533
def get_target (self ):
523
534
return self .target
524
535
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
+
525
579
526
580
class CrashLogFormatException (Exception ):
527
581
pass
@@ -1404,36 +1458,7 @@ def SymbolicateCrashLog(crash_log, options):
1404
1458
if not target :
1405
1459
return
1406
1460
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 )
1437
1462
1438
1463
if crash_log .backtraces :
1439
1464
for thread in crash_log .backtraces :
@@ -1465,6 +1490,7 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
1465
1490
raise InteractiveCrashLogException (
1466
1491
"couldn't create target provided by the user (%s)" % options .target_path
1467
1492
)
1493
+ crashlog .target = target
1468
1494
1469
1495
# 2. If the user didn't provide a target, try to create a target using the symbolicator
1470
1496
if not target or not target .IsValid ():
@@ -1494,7 +1520,11 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
1494
1520
structured_data = lldb .SBStructuredData ()
1495
1521
structured_data .SetFromJSON (
1496
1522
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
+ }
1498
1528
)
1499
1529
)
1500
1530
launch_info = lldb .SBLaunchInfo (None )
@@ -1627,7 +1657,8 @@ def CreateSymbolicateCrashLogOptions(
1627
1657
"--no-crashed-only" ,
1628
1658
action = "store_false" ,
1629
1659
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 ,
1631
1662
)
1632
1663
arg_parser .add_argument (
1633
1664
"--disasm-depth" ,
0 commit comments