Index: lib/asan/scripts/asan_symbolize.py =================================================================== --- lib/asan/scripts/asan_symbolize.py +++ lib/asan/scripts/asan_symbolize.py @@ -24,6 +24,7 @@ fix_filename_patterns = None logfile = sys.stdin allow_system_symbolizer = True +force_system_symbolizer = False # FIXME: merge the code that calls fix_filename(). def fix_filename(file_name): @@ -206,10 +207,10 @@ class DarwinSymbolizer(Symbolizer): - def __init__(self, addr, binary): + def __init__(self, addr, binary, arch): super(DarwinSymbolizer, self).__init__() self.binary = binary - self.arch = guess_arch(addr) + self.arch = arch self.open_atos() def open_atos(self): @@ -268,9 +269,9 @@ return None -def SystemSymbolizerFactory(system, addr, binary): +def SystemSymbolizerFactory(system, addr, binary, arch): if system == 'Darwin': - return DarwinSymbolizer(addr, binary) + return DarwinSymbolizer(addr, binary, arch) elif system == 'Linux' or system == 'FreeBSD': return Addr2LineSymbolizer(binary) @@ -369,7 +370,7 @@ self.frame_no = 0 self.process_line = self.process_line_posix - def symbolize_address(self, addr, binary, offset): + def symbolize_address(self, addr, binary, offset, arch): # On non-Darwin (i.e. on platforms without .dSYM debug info) always use # a single symbolizer binary. # On Darwin, if the dsym hint producer is present: @@ -381,31 +382,35 @@ # if so, reuse |last_llvm_symbolizer| which has the full set of hints; # 3. otherwise create a new symbolizer and pass all currently known # .dSYM hints to it. - if not binary in self.llvm_symbolizers: - use_new_symbolizer = True - if self.system == 'Darwin' and self.dsym_hint_producer: - dsym_hints_for_binary = set(self.dsym_hint_producer(binary)) - use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints) - self.dsym_hints |= dsym_hints_for_binary - if self.last_llvm_symbolizer and not use_new_symbolizer: + result = None + if not force_system_symbolizer: + if not binary in self.llvm_symbolizers: + use_new_symbolizer = True + if self.system == 'Darwin' and self.dsym_hint_producer: + dsym_hints_for_binary = set(self.dsym_hint_producer(binary)) + use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints) + self.dsym_hints |= dsym_hints_for_binary + if self.last_llvm_symbolizer and not use_new_symbolizer: + self.llvm_symbolizers[binary] = self.last_llvm_symbolizer + else: + self.last_llvm_symbolizer = LLVMSymbolizerFactory( + self.system, arch, self.dsym_hints) self.llvm_symbolizers[binary] = self.last_llvm_symbolizer - else: - self.last_llvm_symbolizer = LLVMSymbolizerFactory( - self.system, guess_arch(addr), self.dsym_hints) - self.llvm_symbolizers[binary] = self.last_llvm_symbolizer - # Use the chain of symbolizers: - # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos - # (fall back to next symbolizer if the previous one fails). - if not binary in symbolizers: - symbolizers[binary] = ChainSymbolizer( - [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]]) - result = symbolizers[binary].symbolize(addr, binary, offset) + # Use the chain of symbolizers: + # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos + # (fall back to next symbolizer if the previous one fails). + if not binary in symbolizers: + symbolizers[binary] = ChainSymbolizer( + [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]]) + result = symbolizers[binary].symbolize(addr, binary, offset) + else: + symbolizers[binary] = ChainSymbolizer([]) if result is None: if not allow_system_symbolizer: raise Exception('Failed to launch or use llvm-symbolizer.') # Initialize system symbolizer only if other symbolizers failed. symbolizers[binary].append_symbolizer( - SystemSymbolizerFactory(self.system, addr, binary)) + SystemSymbolizerFactory(self.system, addr, binary, arch)) result = symbolizers[binary].symbolize(addr, binary, offset) # The system symbolizer must produce some result. assert result @@ -433,24 +438,26 @@ def process_line_posix(self, line): self.current_line = line.rstrip() #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) + # or: + #0 0x7f6e35cf2e45 (/blah/foo.so:x86_64+0x11fe45) stack_trace_line_format = ( - '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') + '^( *#([0-9]+) *)(0x[0-9a-f]+) *\(([^:]*)(:(.*))?\+(0x[0-9a-f]+)\)') match = re.match(stack_trace_line_format, line) if not match: return [self.current_line] if DEBUG: print line - _, frameno_str, addr, binary, offset = match.groups() + _, frameno_str, addr, binary, _, arch, offset = match.groups() if frameno_str == '0': # Assume that frame #0 is the first frame of new stack trace. self.frame_no = 0 original_binary = binary if self.binary_name_filter: binary = self.binary_name_filter(binary) - symbolized_line = self.symbolize_address(addr, binary, offset) + symbolized_line = self.symbolize_address(addr, binary, offset, arch) if not symbolized_line: if original_binary != binary: - symbolized_line = self.symbolize_address(addr, binary, offset) + symbolized_line = self.symbolize_address(addr, binary, offset, arch) return self.get_symbolized_lines(symbolized_line) @@ -472,6 +479,8 @@ parser.add_argument('-l','--logfile', default=sys.stdin, type=argparse.FileType('r'), help='set log file name to parse, default is stdin') + parser.add_argument('--force-system-symbolizer', action='store_true', + help='don\'t use llvm-symbolizer') args = parser.parse_args() if args.path_to_cut: fix_filename_patterns = args.path_to_cut @@ -486,5 +495,7 @@ logfile = args.logfile else: logfile = sys.stdin + if args.force_system_symbolizer: + force_system_symbolizer = True loop = SymbolizationLoop(binary_name_filter) loop.process_logfile()