@@ -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
526580class 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" ,
0 commit comments