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

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

Issue 580233003: Revert of Roll asan_symbolize.py to llvm r218071. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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') | no next file » | 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
11 import bisect 10 import bisect
12 import getopt 11 import getopt
13 import os 12 import os
14 import pty 13 import pty
15 import re 14 import re
16 import subprocess 15 import subprocess
17 import sys 16 import sys
18 import termios 17 import termios
19 18
20 symbolizers = {} 19 symbolizers = {}
21 DEBUG = False 20 DEBUG = False
22 demangle = False 21 demangle = False;
23 binutils_prefix = None 22
24 sysroot_path = None
25 binary_name_filter = None
26 fix_filename_patterns = None
27 logfile = None
28 23
29 # FIXME: merge the code that calls fix_filename(). 24 # FIXME: merge the code that calls fix_filename().
30 def fix_filename(file_name): 25 def fix_filename(file_name):
31 if fix_filename_patterns: 26 for path_to_cut in sys.argv[1:]:
32 for path_to_cut in fix_filename_patterns: 27 file_name = re.sub('.*' + path_to_cut, '', file_name)
33 file_name = re.sub('.*' + path_to_cut, '', file_name)
34 file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name) 28 file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name)
35 file_name = re.sub('.*crtstuff.c:0', '???:0', file_name) 29 file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
36 return file_name 30 return file_name
37 31
38 def sysroot_path_filter(binary_name): 32 def GuessArch(addr):
39 return sysroot_path + binary_name
40
41 def guess_arch(addr):
42 # Guess which arch we're running. 10 = len('0x') + 8 hex digits. 33 # Guess which arch we're running. 10 = len('0x') + 8 hex digits.
43 if len(addr) > 10: 34 if len(addr) > 10:
44 return 'x86_64' 35 return 'x86_64'
45 else: 36 else:
46 return 'i386' 37 return 'i386'
47 38
48 class Symbolizer(object): 39 class Symbolizer(object):
49 def __init__(self): 40 def __init__(self):
50 pass 41 pass
51 42
(...skipping 10 matching lines...) Expand all
62 the code locations for this instruction (that is, function name, file 53 the code locations for this instruction (that is, function name, file
63 name, line and column numbers). 54 name, line and column numbers).
64 """ 55 """
65 return None 56 return None
66 57
67 58
68 class LLVMSymbolizer(Symbolizer): 59 class LLVMSymbolizer(Symbolizer):
69 def __init__(self, symbolizer_path, addr): 60 def __init__(self, symbolizer_path, addr):
70 super(LLVMSymbolizer, self).__init__() 61 super(LLVMSymbolizer, self).__init__()
71 self.symbolizer_path = symbolizer_path 62 self.symbolizer_path = symbolizer_path
72 self.default_arch = guess_arch(addr) 63 self.default_arch = GuessArch(addr)
73 self.pipe = self.open_llvm_symbolizer() 64 self.pipe = self.open_llvm_symbolizer()
74 65
75 def open_llvm_symbolizer(self): 66 def open_llvm_symbolizer(self):
76 cmd = [self.symbolizer_path, 67 cmd = [self.symbolizer_path,
77 '--use-symbol-table=true', 68 '--use-symbol-table=true',
78 '--demangle=%s' % demangle, 69 '--demangle=%s' % demangle,
79 '--functions=short', 70 '--functions=short',
80 '--inlining=true', 71 '--inlining=true',
81 '--default-arch=%s' % self.default_arch] 72 '--default-arch=%s' % self.default_arch]
82 if DEBUG: 73 if DEBUG:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 return LLVMSymbolizer(symbolizer_path, addr) 117 return LLVMSymbolizer(symbolizer_path, addr)
127 118
128 119
129 class Addr2LineSymbolizer(Symbolizer): 120 class Addr2LineSymbolizer(Symbolizer):
130 def __init__(self, binary): 121 def __init__(self, binary):
131 super(Addr2LineSymbolizer, self).__init__() 122 super(Addr2LineSymbolizer, self).__init__()
132 self.binary = binary 123 self.binary = binary
133 self.pipe = self.open_addr2line() 124 self.pipe = self.open_addr2line()
134 125
135 def open_addr2line(self): 126 def open_addr2line(self):
136 addr2line_tool = 'addr2line' 127 cmd = ['addr2line', '-f']
137 if binutils_prefix:
138 addr2line_tool = binutils_prefix + addr2line_tool
139 cmd = [addr2line_tool, '-f']
140 if demangle: 128 if demangle:
141 cmd += ['--demangle'] 129 cmd += ['--demangle']
142 cmd += ['-e', self.binary] 130 cmd += ['-e', self.binary]
143 if DEBUG: 131 if DEBUG:
144 print ' '.join(cmd) 132 print ' '.join(cmd)
145 return subprocess.Popen(cmd, 133 return subprocess.Popen(cmd,
146 stdin=subprocess.PIPE, stdout=subprocess.PIPE) 134 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
147 135
148 def symbolize(self, addr, binary, offset): 136 def symbolize(self, addr, binary, offset):
149 """Overrides Symbolizer.symbolize.""" 137 """Overrides Symbolizer.symbolize."""
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 return self.readline() 175 return self.readline()
188 176
189 def readline(self): 177 def readline(self):
190 return self.r.readline().rstrip() 178 return self.r.readline().rstrip()
191 179
192 180
193 class DarwinSymbolizer(Symbolizer): 181 class DarwinSymbolizer(Symbolizer):
194 def __init__(self, addr, binary): 182 def __init__(self, addr, binary):
195 super(DarwinSymbolizer, self).__init__() 183 super(DarwinSymbolizer, self).__init__()
196 self.binary = binary 184 self.binary = binary
197 self.arch = guess_arch(addr) 185 self.arch = GuessArch(addr)
198 self.open_atos() 186 self.open_atos()
199 187
200 def open_atos(self): 188 def open_atos(self):
201 if DEBUG: 189 if DEBUG:
202 print 'atos -o %s -arch %s' % (self.binary, self.arch) 190 print 'atos -o %s -arch %s' % (self.binary, self.arch)
203 cmdline = ['atos', '-o', self.binary, '-arch', self.arch] 191 cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
204 self.atos = UnbufferedLineConverter(cmdline, close_stderr=True) 192 self.atos = UnbufferedLineConverter(cmdline, close_stderr=True)
205 193
206 def symbolize(self, addr, binary, offset): 194 def symbolize(self, addr, binary, offset):
207 """Overrides Symbolizer.symbolize.""" 195 """Overrides Symbolizer.symbolize."""
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 else: 321 else:
334 return None 322 return None
335 323
336 324
337 class SymbolizationLoop(object): 325 class SymbolizationLoop(object):
338 def __init__(self, binary_name_filter=None): 326 def __init__(self, binary_name_filter=None):
339 # 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.
340 # E.g. in Chrome several binaries may share a single .dSYM. 328 # E.g. in Chrome several binaries may share a single .dSYM.
341 self.binary_name_filter = binary_name_filter 329 self.binary_name_filter = binary_name_filter
342 self.system = os.uname()[0] 330 self.system = os.uname()[0]
343 if self.system not in ['Linux', 'Darwin', 'FreeBSD']: 331 if self.system not in ['Linux', 'Darwin']:
344 raise Exception('Unknown system') 332 raise Exception('Unknown system')
345 self.llvm_symbolizer = None 333 self.llvm_symbolizer = None
346 self.frame_no = 0 334 self.frame_no = 0
347 335
348 def symbolize_address(self, addr, binary, offset): 336 def symbolize_address(self, addr, binary, offset):
349 # Initialize llvm-symbolizer lazily. 337 # Initialize llvm-symbolizer lazily.
350 if not self.llvm_symbolizer: 338 if not self.llvm_symbolizer:
351 self.llvm_symbolizer = LLVMSymbolizerFactory(self.system, addr) 339 self.llvm_symbolizer = LLVMSymbolizerFactory(self.system, addr)
352 # Use the chain of symbolizers: 340 # Use the chain of symbolizers:
353 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos 341 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
(...skipping 14 matching lines...) Expand all
368 def get_symbolized_lines(self, symbolized_lines): 356 def get_symbolized_lines(self, symbolized_lines):
369 if not symbolized_lines: 357 if not symbolized_lines:
370 return [self.current_line] 358 return [self.current_line]
371 else: 359 else:
372 result = [] 360 result = []
373 for symbolized_frame in symbolized_lines: 361 for symbolized_frame in symbolized_lines:
374 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri p())) 362 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri p()))
375 self.frame_no += 1 363 self.frame_no += 1
376 return result 364 return result
377 365
378 def process_logfile(self): 366 def process_stdin(self):
379 self.frame_no = 0 367 self.frame_no = 0
380 while True: 368 while True:
381 line = logfile.readline() 369 line = sys.stdin.readline()
382 if not line: 370 if not line:
383 break 371 break
384 processed = self.process_line(line) 372 processed = self.process_line(line)
385 print '\n'.join(processed) 373 print ''.join(processed)
386 374
387 def process_line(self, line): 375 def process_line(self, line):
388 self.current_line = line.rstrip() 376 self.current_line = line.rstrip()
389 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) 377 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
390 stack_trace_line_format = ( 378 stack_trace_line_format = (
391 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') 379 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)')
392 match = re.match(stack_trace_line_format, line) 380 match = re.match(stack_trace_line_format, line)
393 if not match: 381 if not match:
394 return [self.current_line] 382 return [self.current_line]
395 if DEBUG: 383 if DEBUG:
396 print line 384 print line
397 _, frameno_str, addr, binary, offset = match.groups() 385 _, frameno_str, addr, binary, offset = match.groups()
398 if frameno_str == '0': 386 if frameno_str == '0':
399 # Assume that frame #0 is the first frame of new stack trace. 387 # Assume that frame #0 is the first frame of new stack trace.
400 self.frame_no = 0 388 self.frame_no = 0
401 original_binary = binary 389 original_binary = binary
402 if self.binary_name_filter: 390 if self.binary_name_filter:
403 binary = self.binary_name_filter(binary) 391 binary = self.binary_name_filter(binary)
404 symbolized_line = self.symbolize_address(addr, binary, offset) 392 symbolized_line = self.symbolize_address(addr, binary, offset)
405 if not symbolized_line: 393 if not symbolized_line:
406 if original_binary != binary: 394 if original_binary != binary:
407 symbolized_line = self.symbolize_address(addr, binary, offset) 395 symbolized_line = self.symbolize_address(addr, binary, offset)
408 return self.get_symbolized_lines(symbolized_line) 396 return self.get_symbolized_lines(symbolized_line)
409 397
410 398
411 if __name__ == '__main__': 399 if __name__ == '__main__':
412 parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFo rmatter, 400 opts, args = getopt.getopt(sys.argv[1:], "d", ["demangle"])
413 description='ASan symbolization script', 401 for o, a in opts:
414 epilog='''Example of use: 402 if o in ("-d", "--demangle"):
415 asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" -s "$HOME/Symbol Files" < asan.log''') 403 demangle = True;
416 parser.add_argument('path_to_cut', nargs='*', 404 loop = SymbolizationLoop()
417 help='pattern to be cut from the result file path ') 405 loop.process_stdin()
418 parser.add_argument('-d','--demangle', action='store_true',
419 help='demangle function names')
420 parser.add_argument('-s', metavar='SYSROOT',
421 help='set path to sysroot for sanitized binaries')
422 parser.add_argument('-c', metavar='CROSS_COMPILE',
423 help='set prefix for binutils')
424 parser.add_argument('-l','--logfile', default=sys.stdin, type=argparse.FileTyp e('r'),
425 help='set log file name to parse, default is stdin')
426 args = parser.parse_args()
427 if args.path_to_cut:
428 fix_filename_patterns = args.path_to_cut
429 if args.demangle:
430 demangle = True
431 if args.s:
432 binary_name_filter = sysroot_path_filter
433 sysroot_path = args.s
434 if args.c:
435 binutils_prefix = args.c
436 if args.logfile:
437 logfile = args.logfile
438 else:
439 logfile = sys.stdin
440 loop = SymbolizationLoop(binary_name_filter)
441 loop.process_logfile()
OLDNEW
« no previous file with comments | « tools/valgrind/asan/third_party/README.chromium ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698