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

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

Issue 728233003: Reland https://codereview.chromium.org/292153006 with minor changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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/asan_symbolize.py ('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 10 import argparse
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 offset: instruction offset in the @binary. 59 offset: instruction offset in the @binary.
60 Returns: 60 Returns:
61 list of strings (one string for each inlined frame) describing 61 list of strings (one string for each inlined frame) describing
62 the code locations for this instruction (that is, function name, file 62 the code locations for this instruction (that is, function name, file
63 name, line and column numbers). 63 name, line and column numbers).
64 """ 64 """
65 return None 65 return None
66 66
67 67
68 class LLVMSymbolizer(Symbolizer): 68 class LLVMSymbolizer(Symbolizer):
69 def __init__(self, symbolizer_path, addr): 69 def __init__(self, symbolizer_path, default_arch, system, dsym_hints=[]):
70 super(LLVMSymbolizer, self).__init__() 70 super(LLVMSymbolizer, self).__init__()
71 self.symbolizer_path = symbolizer_path 71 self.symbolizer_path = symbolizer_path
72 self.default_arch = guess_arch(addr) 72 self.default_arch = default_arch
73 self.system = system
74 self.dsym_hints = dsym_hints
73 self.pipe = self.open_llvm_symbolizer() 75 self.pipe = self.open_llvm_symbolizer()
74 76
75 def open_llvm_symbolizer(self): 77 def open_llvm_symbolizer(self):
76 cmd = [self.symbolizer_path, 78 cmd = [self.symbolizer_path,
77 '--use-symbol-table=true', 79 '--use-symbol-table=true',
78 '--demangle=%s' % demangle, 80 '--demangle=%s' % demangle,
79 '--functions=short', 81 '--functions=short',
80 '--inlining=true', 82 '--inlining=true',
81 '--default-arch=%s' % self.default_arch] 83 '--default-arch=%s' % self.default_arch]
84 if self.system == 'Darwin':
85 for hint in self.dsym_hints:
86 cmd.append('-dsym-hint=%s' % hint)
82 if DEBUG: 87 if DEBUG:
83 print ' '.join(cmd) 88 print ' '.join(cmd)
84 try: 89 try:
85 result = subprocess.Popen(cmd, stdin=subprocess.PIPE, 90 result = subprocess.Popen(cmd, stdin=subprocess.PIPE,
86 stdout=subprocess.PIPE) 91 stdout=subprocess.PIPE)
87 except OSError: 92 except OSError:
88 result = None 93 result = None
89 return result 94 return result
90 95
91 def symbolize(self, addr, binary, offset): 96 def symbolize(self, addr, binary, offset):
92 """Overrides Symbolizer.symbolize.""" 97 """Overrides Symbolizer.symbolize."""
93 if not self.pipe: 98 if not self.pipe:
94 return None 99 return None
95 result = [] 100 result = []
96 try: 101 try:
97 symbolizer_input = '%s %s' % (binary, offset) 102 symbolizer_input = '"%s" %s' % (binary, offset)
98 if DEBUG: 103 if DEBUG:
99 print symbolizer_input 104 print symbolizer_input
100 print >> self.pipe.stdin, symbolizer_input 105 print >> self.pipe.stdin, symbolizer_input
101 while True: 106 while True:
102 function_name = self.pipe.stdout.readline().rstrip() 107 function_name = self.pipe.stdout.readline().rstrip()
103 if not function_name: 108 if not function_name:
104 break 109 break
105 file_name = self.pipe.stdout.readline().rstrip() 110 file_name = self.pipe.stdout.readline().rstrip()
106 file_name = fix_filename(file_name) 111 file_name = fix_filename(file_name)
107 if (not function_name.startswith('??') or 112 if (not function_name.startswith('??') or
108 not file_name.startswith('??')): 113 not file_name.startswith('??')):
109 # Append only non-trivial frames. 114 # Append only non-trivial frames.
110 result.append('%s in %s %s' % (addr, function_name, 115 result.append('%s in %s %s' % (addr, function_name,
111 file_name)) 116 file_name))
112 except Exception: 117 except Exception:
113 result = [] 118 result = []
114 if not result: 119 if not result:
115 result = None 120 result = None
116 return result 121 return result
117 122
118 123
119 def LLVMSymbolizerFactory(system, addr): 124 def LLVMSymbolizerFactory(system, default_arch, dsym_hints=[]):
120 symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH') 125 symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')
121 if not symbolizer_path: 126 if not symbolizer_path:
122 symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH') 127 symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH')
123 if not symbolizer_path: 128 if not symbolizer_path:
124 # Assume llvm-symbolizer is in PATH. 129 # Assume llvm-symbolizer is in PATH.
125 symbolizer_path = 'llvm-symbolizer' 130 symbolizer_path = 'llvm-symbolizer'
126 return LLVMSymbolizer(symbolizer_path, addr) 131 return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints)
127 132
128 133
129 class Addr2LineSymbolizer(Symbolizer): 134 class Addr2LineSymbolizer(Symbolizer):
130 def __init__(self, binary): 135 def __init__(self, binary):
131 super(Addr2LineSymbolizer, self).__init__() 136 super(Addr2LineSymbolizer, self).__init__()
132 self.binary = binary 137 self.binary = binary
133 self.pipe = self.open_addr2line() 138 self.pipe = self.open_addr2line()
134 139
135 def open_addr2line(self): 140 def open_addr2line(self):
136 addr2line_tool = 'addr2line' 141 addr2line_tool = 'addr2line'
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 function_name, file_name, line_no = res 333 function_name, file_name, line_no = res
329 result = ['%s in %s %s:%d' % ( 334 result = ['%s in %s %s:%d' % (
330 addr, function_name, file_name, line_no)] 335 addr, function_name, file_name, line_no)]
331 print result 336 print result
332 return result 337 return result
333 else: 338 else:
334 return None 339 return None
335 340
336 341
337 class SymbolizationLoop(object): 342 class SymbolizationLoop(object):
338 def __init__(self, binary_name_filter=None): 343 def __init__(self, binary_name_filter=None, dsym_hint_producer=None):
339 # Used by clients who may want to supply a different binary name. 344 # Used by clients who may want to supply a different binary name.
340 # E.g. in Chrome several binaries may share a single .dSYM. 345 # E.g. in Chrome several binaries may share a single .dSYM.
341 self.binary_name_filter = binary_name_filter 346 self.binary_name_filter = binary_name_filter
347 self.dsym_hint_producer = dsym_hint_producer
342 self.system = os.uname()[0] 348 self.system = os.uname()[0]
343 if self.system not in ['Linux', 'Darwin', 'FreeBSD']: 349 if self.system not in ['Linux', 'Darwin', 'FreeBSD']:
344 raise Exception('Unknown system') 350 raise Exception('Unknown system')
345 self.llvm_symbolizer = None 351 self.llvm_symbolizers = {}
352 self.last_llvm_symbolizer = None
353 self.dsym_hints = set([])
346 self.frame_no = 0 354 self.frame_no = 0
347 355
348 def symbolize_address(self, addr, binary, offset): 356 def symbolize_address(self, addr, binary, offset):
349 # Initialize llvm-symbolizer lazily. 357 # On non-Darwin (i.e. on platforms without .dSYM debug info) always use
350 if not self.llvm_symbolizer: 358 # a single symbolizer binary.
351 self.llvm_symbolizer = LLVMSymbolizerFactory(self.system, addr) 359 # On Darwin, if the dsym hint producer is present:
360 # 1. check whether we've seen this binary already; if so,
361 # use |llvm_symbolizers[binary]|;
362 # 2. otherwise check if we've seen this hint already; if so,
363 # reuse |last_llvm_symbolizer|;
364 # 3. otherwise create a new symbolizer and pass all currently known
365 # .dSYM hints to it.
366 use_last_symbolizer = True
367 if not binary in self.llvm_symbolizers:
368 if self.system == 'Darwin' and self.dsym_hint_producer:
369 dsym_hints = self.dsym_hint_producer(binary)
370 for dsym_hint in dsym_hints:
371 if not dsym_hint in self.dsym_hints:
372 use_last_symbolizer = False
373 self.dsym_hints.add(dsym_hint)
374 if self.last_llvm_symbolizer and use_last_symbolizer:
375 self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
376 else:
377 self.last_llvm_symbolizer = LLVMSymbolizerFactory(
378 self.system, guess_arch(addr), self.dsym_hints)
379 self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
352 # Use the chain of symbolizers: 380 # Use the chain of symbolizers:
353 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos 381 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
354 # (fall back to next symbolizer if the previous one fails). 382 # (fall back to next symbolizer if the previous one fails).
355 if not binary in symbolizers: 383 if not binary in symbolizers:
356 symbolizers[binary] = ChainSymbolizer( 384 symbolizers[binary] = ChainSymbolizer(
357 [BreakpadSymbolizerFactory(binary), self.llvm_symbolizer]) 385 [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
358 result = symbolizers[binary].symbolize(addr, binary, offset) 386 result = symbolizers[binary].symbolize(addr, binary, offset)
359 if result is None: 387 if result is None:
360 # Initialize system symbolizer only if other symbolizers failed. 388 # Initialize system symbolizer only if other symbolizers failed.
361 symbolizers[binary].append_symbolizer( 389 symbolizers[binary].append_symbolizer(
362 SystemSymbolizerFactory(self.system, addr, binary)) 390 SystemSymbolizerFactory(self.system, addr, binary))
363 result = symbolizers[binary].symbolize(addr, binary, offset) 391 result = symbolizers[binary].symbolize(addr, binary, offset)
364 # The system symbolizer must produce some result. 392 # The system symbolizer must produce some result.
365 assert result 393 assert result
366 return result 394 return result
367 395
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 binary_name_filter = sysroot_path_filter 460 binary_name_filter = sysroot_path_filter
433 sysroot_path = args.s 461 sysroot_path = args.s
434 if args.c: 462 if args.c:
435 binutils_prefix = args.c 463 binutils_prefix = args.c
436 if args.logfile: 464 if args.logfile:
437 logfile = args.logfile 465 logfile = args.logfile
438 else: 466 else:
439 logfile = sys.stdin 467 logfile = sys.stdin
440 loop = SymbolizationLoop(binary_name_filter) 468 loop = SymbolizationLoop(binary_name_filter)
441 loop.process_logfile() 469 loop.process_logfile()
OLDNEW
« no previous file with comments | « tools/valgrind/asan/asan_symbolize.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698