Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: tools/valgrind/asan/third_party/asan_symbolize.py

Issue 895853003: Update from https://crrev.com/314320 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/valgrind/asan/third_party/README.chromium ('k') | tools/valgrind/drmemory/PRESUBMIT.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 argparse 10 import argparse
11 import bisect 11 import bisect
12 import getopt 12 import getopt
13 import os 13 import os
14 import pty
15 import re 14 import re
16 import subprocess 15 import subprocess
17 import sys 16 import sys
18 import termios
19 17
20 symbolizers = {} 18 symbolizers = {}
21 DEBUG = False 19 DEBUG = False
22 demangle = False 20 demangle = False
23 binutils_prefix = None 21 binutils_prefix = None
24 sysroot_path = None 22 sysroot_path = None
25 binary_name_filter = None 23 binary_name_filter = None
26 fix_filename_patterns = None 24 fix_filename_patterns = None
27 logfile = sys.stdin 25 logfile = sys.stdin
28 26
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 file_name = fix_filename(file_name) 162 file_name = fix_filename(file_name)
165 return ['%s in %s %s' % (addr, function_name, file_name)] 163 return ['%s in %s %s' % (addr, function_name, file_name)]
166 164
167 165
168 class UnbufferedLineConverter(object): 166 class UnbufferedLineConverter(object):
169 """ 167 """
170 Wrap a child process that responds to each line of input with one line of 168 Wrap a child process that responds to each line of input with one line of
171 output. Uses pty to trick the child into providing unbuffered output. 169 output. Uses pty to trick the child into providing unbuffered output.
172 """ 170 """
173 def __init__(self, args, close_stderr=False): 171 def __init__(self, args, close_stderr=False):
172 # Local imports so that the script can start on Windows.
173 import pty
174 import termios
174 pid, fd = pty.fork() 175 pid, fd = pty.fork()
175 if pid == 0: 176 if pid == 0:
176 # We're the child. Transfer control to command. 177 # We're the child. Transfer control to command.
177 if close_stderr: 178 if close_stderr:
178 dev_null = os.open('/dev/null', 0) 179 dev_null = os.open('/dev/null', 0)
179 os.dup2(dev_null, 2) 180 os.dup2(dev_null, 2)
180 os.execvp(args[0], args) 181 os.execvp(args[0], args)
181 else: 182 else:
182 # Disable echoing. 183 # Disable echoing.
183 attr = termios.tcgetattr(fd) 184 attr = termios.tcgetattr(fd)
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 result = ['%s in %s %s:%d' % ( 335 result = ['%s in %s %s:%d' % (
335 addr, function_name, file_name, line_no)] 336 addr, function_name, file_name, line_no)]
336 print result 337 print result
337 return result 338 return result
338 else: 339 else:
339 return None 340 return None
340 341
341 342
342 class SymbolizationLoop(object): 343 class SymbolizationLoop(object):
343 def __init__(self, binary_name_filter=None, dsym_hint_producer=None): 344 def __init__(self, binary_name_filter=None, dsym_hint_producer=None):
344 # Used by clients who may want to supply a different binary name. 345 if sys.platform == 'win32':
345 # E.g. in Chrome several binaries may share a single .dSYM. 346 # ASan on Windows uses dbghelp.dll to symbolize in-process, which works
346 self.binary_name_filter = binary_name_filter 347 # even in sandboxed processes. Nothing needs to be done here.
347 self.dsym_hint_producer = dsym_hint_producer 348 self.process_line = self.process_line_echo
348 self.system = os.uname()[0] 349 else:
349 if self.system not in ['Linux', 'Darwin', 'FreeBSD']: 350 # Used by clients who may want to supply a different binary name.
350 raise Exception('Unknown system') 351 # E.g. in Chrome several binaries may share a single .dSYM.
351 self.llvm_symbolizers = {} 352 self.binary_name_filter = binary_name_filter
352 self.last_llvm_symbolizer = None 353 self.dsym_hint_producer = dsym_hint_producer
353 self.dsym_hints = set([]) 354 self.system = os.uname()[0]
354 self.frame_no = 0 355 if self.system not in ['Linux', 'Darwin', 'FreeBSD']:
356 raise Exception('Unknown system')
357 self.llvm_symbolizers = {}
358 self.last_llvm_symbolizer = None
359 self.dsym_hints = set([])
360 self.frame_no = 0
361 self.process_line = self.process_line_posix
355 362
356 def symbolize_address(self, addr, binary, offset): 363 def symbolize_address(self, addr, binary, offset):
357 # On non-Darwin (i.e. on platforms without .dSYM debug info) always use 364 # On non-Darwin (i.e. on platforms without .dSYM debug info) always use
358 # a single symbolizer binary. 365 # a single symbolizer binary.
359 # On Darwin, if the dsym hint producer is present: 366 # On Darwin, if the dsym hint producer is present:
360 # 1. check whether we've seen this binary already; if so, 367 # 1. check whether we've seen this binary already; if so,
361 # use |llvm_symbolizers[binary]|, which has already loaded the debug 368 # use |llvm_symbolizers[binary]|, which has already loaded the debug
362 # info for this binary (might not be the case for 369 # info for this binary (might not be the case for
363 # |last_llvm_symbolizer|); 370 # |last_llvm_symbolizer|);
364 # 2. otherwise check if we've seen all the hints for this binary already; 371 # 2. otherwise check if we've seen all the hints for this binary already;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 return [self.current_line] 405 return [self.current_line]
399 else: 406 else:
400 result = [] 407 result = []
401 for symbolized_frame in symbolized_lines: 408 for symbolized_frame in symbolized_lines:
402 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri p())) 409 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri p()))
403 self.frame_no += 1 410 self.frame_no += 1
404 return result 411 return result
405 412
406 def process_logfile(self): 413 def process_logfile(self):
407 self.frame_no = 0 414 self.frame_no = 0
408 while True: 415 for line in logfile:
409 line = logfile.readline()
410 if not line:
411 break
412 processed = self.process_line(line) 416 processed = self.process_line(line)
413 print '\n'.join(processed) 417 print '\n'.join(processed)
414 418
415 def process_line(self, line): 419 def process_line_echo(self, line):
420 return [line.rstrip()]
421
422 def process_line_posix(self, line):
416 self.current_line = line.rstrip() 423 self.current_line = line.rstrip()
417 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) 424 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
418 stack_trace_line_format = ( 425 stack_trace_line_format = (
419 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') 426 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)')
420 match = re.match(stack_trace_line_format, line) 427 match = re.match(stack_trace_line_format, line)
421 if not match: 428 if not match:
422 return [self.current_line] 429 return [self.current_line]
423 if DEBUG: 430 if DEBUG:
424 print line 431 print line
425 _, frameno_str, addr, binary, offset = match.groups() 432 _, frameno_str, addr, binary, offset = match.groups()
426 if frameno_str == '0': 433 if frameno_str == '0':
427 # Assume that frame #0 is the first frame of new stack trace. 434 # Assume that frame #0 is the first frame of new stack trace.
428 self.frame_no = 0 435 self.frame_no = 0
429 original_binary = binary 436 original_binary = binary
430 if self.binary_name_filter: 437 if self.binary_name_filter:
431 binary = self.binary_name_filter(binary) 438 binary = self.binary_name_filter(binary)
432 symbolized_line = self.symbolize_address(addr, binary, offset) 439 symbolized_line = self.symbolize_address(addr, binary, offset)
433 if not symbolized_line: 440 if not symbolized_line:
434 if original_binary != binary: 441 if original_binary != binary:
435 symbolized_line = self.symbolize_address(addr, binary, offset) 442 symbolized_line = self.symbolize_address(addr, binary, offset)
436 return self.get_symbolized_lines(symbolized_line) 443 return self.get_symbolized_lines(symbolized_line)
437 444
438 445
439 if __name__ == '__main__': 446 if __name__ == '__main__':
440 parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFo rmatter, 447 parser = argparse.ArgumentParser(
441 description='ASan symbolization script', 448 formatter_class=argparse.RawDescriptionHelpFormatter,
442 epilog='''Example of use: 449 description='ASan symbolization script',
443 asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" -s "$HOME/Symbol Files" < asan.log''') 450 epilog='Example of use:\n'
451 'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" '
452 '-s "$HOME/SymbolFiles" < asan.log')
444 parser.add_argument('path_to_cut', nargs='*', 453 parser.add_argument('path_to_cut', nargs='*',
445 help='pattern to be cut from the result file path ') 454 help='pattern to be cut from the result file path ')
446 parser.add_argument('-d','--demangle', action='store_true', 455 parser.add_argument('-d','--demangle', action='store_true',
447 help='demangle function names') 456 help='demangle function names')
448 parser.add_argument('-s', metavar='SYSROOT', 457 parser.add_argument('-s', metavar='SYSROOT',
449 help='set path to sysroot for sanitized binaries') 458 help='set path to sysroot for sanitized binaries')
450 parser.add_argument('-c', metavar='CROSS_COMPILE', 459 parser.add_argument('-c', metavar='CROSS_COMPILE',
451 help='set prefix for binutils') 460 help='set prefix for binutils')
452 parser.add_argument('-l','--logfile', default=sys.stdin, type=argparse.FileTyp e('r'), 461 parser.add_argument('-l','--logfile', default=sys.stdin,
453 help='set log file name to parse, default is stdin') 462 type=argparse.FileType('r'),
463 help='set log file name to parse, default is stdin')
454 args = parser.parse_args() 464 args = parser.parse_args()
455 if args.path_to_cut: 465 if args.path_to_cut:
456 fix_filename_patterns = args.path_to_cut 466 fix_filename_patterns = args.path_to_cut
457 if args.demangle: 467 if args.demangle:
458 demangle = True 468 demangle = True
459 if args.s: 469 if args.s:
460 binary_name_filter = sysroot_path_filter 470 binary_name_filter = sysroot_path_filter
461 sysroot_path = args.s 471 sysroot_path = args.s
462 if args.c: 472 if args.c:
463 binutils_prefix = args.c 473 binutils_prefix = args.c
464 if args.logfile: 474 if args.logfile:
465 logfile = args.logfile 475 logfile = args.logfile
466 else: 476 else:
467 logfile = sys.stdin 477 logfile = sys.stdin
468 loop = SymbolizationLoop(binary_name_filter) 478 loop = SymbolizationLoop(binary_name_filter)
469 loop.process_logfile() 479 loop.process_logfile()
OLDNEW
« no previous file with comments | « tools/valgrind/asan/third_party/README.chromium ('k') | tools/valgrind/drmemory/PRESUBMIT.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698