| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 #===- lib/asan/scripts/asan_symbolize.py -----------------------------------===# | 2 #===- lib/asan/scripts/asan_symbolize.py -----------------------------------===# |
| 3 # | 3 # |
| 4 # The LLVM Compiler Infrastructure | 4 # The LLVM Compiler Infrastructure |
| 5 # | 5 # |
| 6 # This file is distributed under the University of Illinois Open Source | 6 # This file is distributed under the University of Illinois Open Source |
| 7 # License. See LICENSE.TXT for details. | 7 # License. See LICENSE.TXT for details. |
| 8 # | 8 # |
| 9 #===------------------------------------------------------------------------===# | 9 #===------------------------------------------------------------------------===# |
| 10 import bisect | 10 import bisect |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 324 |
| 325 class SymbolizationLoop(object): | 325 class SymbolizationLoop(object): |
| 326 def __init__(self, binary_name_filter=None): | 326 def __init__(self, binary_name_filter=None): |
| 327 # Used by clients who may want to supply a different binary name. | 327 # Used by clients who may want to supply a different binary name. |
| 328 # E.g. in Chrome several binaries may share a single .dSYM. | 328 # E.g. in Chrome several binaries may share a single .dSYM. |
| 329 self.binary_name_filter = binary_name_filter | 329 self.binary_name_filter = binary_name_filter |
| 330 self.system = os.uname()[0] | 330 self.system = os.uname()[0] |
| 331 if self.system not in ['Linux', 'Darwin']: | 331 if self.system not in ['Linux', 'Darwin']: |
| 332 raise Exception('Unknown system') | 332 raise Exception('Unknown system') |
| 333 self.llvm_symbolizer = None | 333 self.llvm_symbolizer = None |
| 334 self.frame_no = 0 |
| 334 | 335 |
| 335 def symbolize_address(self, addr, binary, offset): | 336 def symbolize_address(self, addr, binary, offset): |
| 336 # Initialize llvm-symbolizer lazily. | 337 # Initialize llvm-symbolizer lazily. |
| 337 if not self.llvm_symbolizer: | 338 if not self.llvm_symbolizer: |
| 338 self.llvm_symbolizer = LLVMSymbolizerFactory(self.system, addr) | 339 self.llvm_symbolizer = LLVMSymbolizerFactory(self.system, addr) |
| 339 # Use the chain of symbolizers: | 340 # Use the chain of symbolizers: |
| 340 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos | 341 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos |
| 341 # (fall back to next symbolizer if the previous one fails). | 342 # (fall back to next symbolizer if the previous one fails). |
| 342 if not binary in symbolizers: | 343 if not binary in symbolizers: |
| 343 symbolizers[binary] = ChainSymbolizer( | 344 symbolizers[binary] = ChainSymbolizer( |
| 344 [BreakpadSymbolizerFactory(binary), self.llvm_symbolizer]) | 345 [BreakpadSymbolizerFactory(binary), self.llvm_symbolizer]) |
| 345 result = symbolizers[binary].symbolize(addr, binary, offset) | 346 result = symbolizers[binary].symbolize(addr, binary, offset) |
| 346 if result is None: | 347 if result is None: |
| 347 # Initialize system symbolizer only if other symbolizers failed. | 348 # Initialize system symbolizer only if other symbolizers failed. |
| 348 symbolizers[binary].append_symbolizer( | 349 symbolizers[binary].append_symbolizer( |
| 349 SystemSymbolizerFactory(self.system, addr, binary)) | 350 SystemSymbolizerFactory(self.system, addr, binary)) |
| 350 result = symbolizers[binary].symbolize(addr, binary, offset) | 351 result = symbolizers[binary].symbolize(addr, binary, offset) |
| 351 # The system symbolizer must produce some result. | 352 # The system symbolizer must produce some result. |
| 352 assert result | 353 assert result |
| 353 return result | 354 return result |
| 354 | 355 |
| 355 def print_symbolized_lines(self, symbolized_lines): | 356 def get_symbolized_lines(self, symbolized_lines): |
| 356 if not symbolized_lines: | 357 if not symbolized_lines: |
| 357 print self.current_line | 358 return [self.current_line] |
| 358 else: | 359 else: |
| 360 result = [] |
| 359 for symbolized_frame in symbolized_lines: | 361 for symbolized_frame in symbolized_lines: |
| 360 print ' #' + str(self.frame_no) + ' ' + symbolized_frame.rstrip() | 362 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri
p())) |
| 361 self.frame_no += 1 | 363 self.frame_no += 1 |
| 364 return result |
| 362 | 365 |
| 363 def process_stdin(self): | 366 def process_stdin(self): |
| 364 self.frame_no = 0 | 367 self.frame_no = 0 |
| 365 while True: | 368 while True: |
| 366 line = sys.stdin.readline() | 369 line = sys.stdin.readline() |
| 367 if not line: | 370 if not line: |
| 368 break | 371 break |
| 369 self.current_line = line.rstrip() | 372 processed = self.process_line(line) |
| 370 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) | 373 print ''.join(processed) |
| 371 stack_trace_line_format = ( | 374 |
| 372 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') | 375 def process_line(self, line): |
| 373 match = re.match(stack_trace_line_format, line) | 376 self.current_line = line.rstrip() |
| 374 if not match: | 377 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) |
| 375 print self.current_line | 378 stack_trace_line_format = ( |
| 376 continue | 379 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') |
| 377 if DEBUG: | 380 match = re.match(stack_trace_line_format, line) |
| 378 print line | 381 if not match: |
| 379 _, frameno_str, addr, binary, offset = match.groups() | 382 return [self.current_line] |
| 380 if frameno_str == '0': | 383 if DEBUG: |
| 381 # Assume that frame #0 is the first frame of new stack trace. | 384 print line |
| 382 self.frame_no = 0 | 385 _, frameno_str, addr, binary, offset = match.groups() |
| 383 original_binary = binary | 386 if frameno_str == '0': |
| 384 if self.binary_name_filter: | 387 # Assume that frame #0 is the first frame of new stack trace. |
| 385 binary = self.binary_name_filter(binary) | 388 self.frame_no = 0 |
| 386 symbolized_line = self.symbolize_address(addr, binary, offset) | 389 original_binary = binary |
| 387 if not symbolized_line: | 390 if self.binary_name_filter: |
| 388 if original_binary != binary: | 391 binary = self.binary_name_filter(binary) |
| 389 symbolized_line = self.symbolize_address(addr, binary, offset) | 392 symbolized_line = self.symbolize_address(addr, binary, offset) |
| 390 self.print_symbolized_lines(symbolized_line) | 393 if not symbolized_line: |
| 394 if original_binary != binary: |
| 395 symbolized_line = self.symbolize_address(addr, binary, offset) |
| 396 return self.get_symbolized_lines(symbolized_line) |
| 391 | 397 |
| 392 | 398 |
| 393 if __name__ == '__main__': | 399 if __name__ == '__main__': |
| 394 opts, args = getopt.getopt(sys.argv[1:], "d", ["demangle"]) | 400 opts, args = getopt.getopt(sys.argv[1:], "d", ["demangle"]) |
| 395 for o, a in opts: | 401 for o, a in opts: |
| 396 if o in ("-d", "--demangle"): | 402 if o in ("-d", "--demangle"): |
| 397 demangle = True; | 403 demangle = True; |
| 398 loop = SymbolizationLoop() | 404 loop = SymbolizationLoop() |
| 399 loop.process_stdin() | 405 loop.process_stdin() |
| OLD | NEW |