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

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

Issue 2739213005: Roll tools/valgrind/asan/third_party/asan_symbolize.py 227327:294450 (Closed)
Patch Set: Created 3 years, 9 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 | « no previous file | 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
11 import bisect 11 import bisect
12 import getopt 12 import getopt
13 import os 13 import os
14 import re 14 import re
15 import subprocess 15 import subprocess
16 import sys 16 import sys
17 17
18 symbolizers = {} 18 symbolizers = {}
19 DEBUG = False 19 DEBUG = False
20 demangle = False 20 demangle = False
21 binutils_prefix = None 21 binutils_prefix = None
22 sysroot_path = None 22 sysroot_path = None
23 binary_name_filter = None 23 binary_name_filter = None
24 fix_filename_patterns = None 24 fix_filename_patterns = None
25 logfile = sys.stdin 25 logfile = sys.stdin
26 allow_system_symbolizer = True
27 force_system_symbolizer = False
26 28
27 # FIXME: merge the code that calls fix_filename(). 29 # FIXME: merge the code that calls fix_filename().
28 def fix_filename(file_name): 30 def fix_filename(file_name):
29 if fix_filename_patterns: 31 if fix_filename_patterns:
30 for path_to_cut in fix_filename_patterns: 32 for path_to_cut in fix_filename_patterns:
31 file_name = re.sub('.*' + path_to_cut, '', file_name) 33 file_name = re.sub('.*' + path_to_cut, '', file_name)
32 file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name) 34 file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name)
33 file_name = re.sub('.*crtstuff.c:0', '???:0', file_name) 35 file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
34 return file_name 36 return file_name
35 37
36 def sysroot_path_filter(binary_name): 38 def sysroot_path_filter(binary_name):
37 return sysroot_path + binary_name 39 return sysroot_path + binary_name
38 40
41 def is_valid_arch(s):
42 return s in ["i386", "x86_64", "x86_64h", "arm", "armv6", "armv7", "armv7s",
43 "armv7k", "arm64", "powerpc64", "powerpc64le", "s390x", "s390"]
44
39 def guess_arch(addr): 45 def guess_arch(addr):
40 # Guess which arch we're running. 10 = len('0x') + 8 hex digits. 46 # Guess which arch we're running. 10 = len('0x') + 8 hex digits.
41 if len(addr) > 10: 47 if len(addr) > 10:
42 return 'x86_64' 48 return 'x86_64'
43 else: 49 else:
44 return 'i386' 50 return 'i386'
45 51
46 class Symbolizer(object): 52 class Symbolizer(object):
47 def __init__(self): 53 def __init__(self):
48 pass 54 pass
(...skipping 20 matching lines...) Expand all
69 self.symbolizer_path = symbolizer_path 75 self.symbolizer_path = symbolizer_path
70 self.default_arch = default_arch 76 self.default_arch = default_arch
71 self.system = system 77 self.system = system
72 self.dsym_hints = dsym_hints 78 self.dsym_hints = dsym_hints
73 self.pipe = self.open_llvm_symbolizer() 79 self.pipe = self.open_llvm_symbolizer()
74 80
75 def open_llvm_symbolizer(self): 81 def open_llvm_symbolizer(self):
76 cmd = [self.symbolizer_path, 82 cmd = [self.symbolizer_path,
77 '--use-symbol-table=true', 83 '--use-symbol-table=true',
78 '--demangle=%s' % demangle, 84 '--demangle=%s' % demangle,
79 '--functions=short', 85 '--functions=linkage',
80 '--inlining=true', 86 '--inlining=true',
81 '--default-arch=%s' % self.default_arch] 87 '--default-arch=%s' % self.default_arch]
82 if self.system == 'Darwin': 88 if self.system == 'Darwin':
83 for hint in self.dsym_hints: 89 for hint in self.dsym_hints:
84 cmd.append('--dsym-hint=%s' % hint) 90 cmd.append('--dsym-hint=%s' % hint)
85 if DEBUG: 91 if DEBUG:
86 print ' '.join(cmd) 92 print(' '.join(cmd))
87 try: 93 try:
88 result = subprocess.Popen(cmd, stdin=subprocess.PIPE, 94 result = subprocess.Popen(cmd, stdin=subprocess.PIPE,
89 stdout=subprocess.PIPE) 95 stdout=subprocess.PIPE,
96 bufsize=0,
97 universal_newlines=True)
90 except OSError: 98 except OSError:
91 result = None 99 result = None
92 return result 100 return result
93 101
94 def symbolize(self, addr, binary, offset): 102 def symbolize(self, addr, binary, offset):
95 """Overrides Symbolizer.symbolize.""" 103 """Overrides Symbolizer.symbolize."""
96 if not self.pipe: 104 if not self.pipe:
97 return None 105 return None
98 result = [] 106 result = []
99 try: 107 try:
100 symbolizer_input = '"%s" %s' % (binary, offset) 108 symbolizer_input = '"%s" %s' % (binary, offset)
101 if DEBUG: 109 if DEBUG:
102 print symbolizer_input 110 print(symbolizer_input)
103 print >> self.pipe.stdin, symbolizer_input 111 self.pipe.stdin.write("%s\n" % symbolizer_input)
104 while True: 112 while True:
105 function_name = self.pipe.stdout.readline().rstrip() 113 function_name = self.pipe.stdout.readline().rstrip()
106 if not function_name: 114 if not function_name:
107 break 115 break
108 file_name = self.pipe.stdout.readline().rstrip() 116 file_name = self.pipe.stdout.readline().rstrip()
109 file_name = fix_filename(file_name) 117 file_name = fix_filename(file_name)
110 if (not function_name.startswith('??') or 118 if (not function_name.startswith('??') or
111 not file_name.startswith('??')): 119 not file_name.startswith('??')):
112 # Append only non-trivial frames. 120 # Append only non-trivial frames.
113 result.append('%s in %s %s' % (addr, function_name, 121 result.append('%s in %s %s' % (addr, function_name,
(...skipping 13 matching lines...) Expand all
127 # Assume llvm-symbolizer is in PATH. 135 # Assume llvm-symbolizer is in PATH.
128 symbolizer_path = 'llvm-symbolizer' 136 symbolizer_path = 'llvm-symbolizer'
129 return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints) 137 return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints)
130 138
131 139
132 class Addr2LineSymbolizer(Symbolizer): 140 class Addr2LineSymbolizer(Symbolizer):
133 def __init__(self, binary): 141 def __init__(self, binary):
134 super(Addr2LineSymbolizer, self).__init__() 142 super(Addr2LineSymbolizer, self).__init__()
135 self.binary = binary 143 self.binary = binary
136 self.pipe = self.open_addr2line() 144 self.pipe = self.open_addr2line()
145 self.output_terminator = -1
137 146
138 def open_addr2line(self): 147 def open_addr2line(self):
139 addr2line_tool = 'addr2line' 148 addr2line_tool = 'addr2line'
140 if binutils_prefix: 149 if binutils_prefix:
141 addr2line_tool = binutils_prefix + addr2line_tool 150 addr2line_tool = binutils_prefix + addr2line_tool
142 cmd = [addr2line_tool, '-f'] 151 cmd = [addr2line_tool, '-fi']
143 if demangle: 152 if demangle:
144 cmd += ['--demangle'] 153 cmd += ['--demangle']
145 cmd += ['-e', self.binary] 154 cmd += ['-e', self.binary]
146 if DEBUG: 155 if DEBUG:
147 print ' '.join(cmd) 156 print(' '.join(cmd))
148 return subprocess.Popen(cmd, 157 return subprocess.Popen(cmd,
149 stdin=subprocess.PIPE, stdout=subprocess.PIPE) 158 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
159 bufsize=0,
160 universal_newlines=True)
150 161
151 def symbolize(self, addr, binary, offset): 162 def symbolize(self, addr, binary, offset):
152 """Overrides Symbolizer.symbolize.""" 163 """Overrides Symbolizer.symbolize."""
153 if self.binary != binary: 164 if self.binary != binary:
154 return None 165 return None
166 lines = []
155 try: 167 try:
156 print >> self.pipe.stdin, offset 168 self.pipe.stdin.write("%s\n" % offset)
157 function_name = self.pipe.stdout.readline().rstrip() 169 self.pipe.stdin.write("%s\n" % self.output_terminator)
158 file_name = self.pipe.stdout.readline().rstrip() 170 is_first_frame = True
171 while True:
172 function_name = self.pipe.stdout.readline().rstrip()
173 file_name = self.pipe.stdout.readline().rstrip()
174 if is_first_frame:
175 is_first_frame = False
176 elif function_name in ['', '??']:
177 assert file_name == function_name
178 break
179 lines.append((function_name, file_name));
159 except Exception: 180 except Exception:
160 function_name = '' 181 lines.append(('??', '??:0'))
161 file_name = '' 182 return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines]
162 file_name = fix_filename(file_name)
163 return ['%s in %s %s' % (addr, function_name, file_name)]
164
165 183
166 class UnbufferedLineConverter(object): 184 class UnbufferedLineConverter(object):
167 """ 185 """
168 Wrap a child process that responds to each line of input with one line of 186 Wrap a child process that responds to each line of input with one line of
169 output. Uses pty to trick the child into providing unbuffered output. 187 output. Uses pty to trick the child into providing unbuffered output.
170 """ 188 """
171 def __init__(self, args, close_stderr=False): 189 def __init__(self, args, close_stderr=False):
172 # Local imports so that the script can start on Windows. 190 # Local imports so that the script can start on Windows.
173 import pty 191 import pty
174 import termios 192 import termios
(...skipping 15 matching lines...) Expand all
190 208
191 def convert(self, line): 209 def convert(self, line):
192 self.w.write(line + "\n") 210 self.w.write(line + "\n")
193 return self.readline() 211 return self.readline()
194 212
195 def readline(self): 213 def readline(self):
196 return self.r.readline().rstrip() 214 return self.r.readline().rstrip()
197 215
198 216
199 class DarwinSymbolizer(Symbolizer): 217 class DarwinSymbolizer(Symbolizer):
200 def __init__(self, addr, binary): 218 def __init__(self, addr, binary, arch):
201 super(DarwinSymbolizer, self).__init__() 219 super(DarwinSymbolizer, self).__init__()
202 self.binary = binary 220 self.binary = binary
203 self.arch = guess_arch(addr) 221 self.arch = arch
204 self.open_atos() 222 self.open_atos()
205 223
206 def open_atos(self): 224 def open_atos(self):
207 if DEBUG: 225 if DEBUG:
208 print 'atos -o %s -arch %s' % (self.binary, self.arch) 226 print('atos -o %s -arch %s' % (self.binary, self.arch))
209 cmdline = ['atos', '-o', self.binary, '-arch', self.arch] 227 cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
210 self.atos = UnbufferedLineConverter(cmdline, close_stderr=True) 228 self.atos = UnbufferedLineConverter(cmdline, close_stderr=True)
211 229
212 def symbolize(self, addr, binary, offset): 230 def symbolize(self, addr, binary, offset):
213 """Overrides Symbolizer.symbolize.""" 231 """Overrides Symbolizer.symbolize."""
214 if self.binary != binary: 232 if self.binary != binary:
215 return None 233 return None
216 atos_line = self.atos.convert('0x%x' % int(offset, 16)) 234 atos_line = self.atos.convert('0x%x' % int(offset, 16))
217 while "got symbolicator for" in atos_line: 235 while "got symbolicator for" in atos_line:
218 atos_line = self.atos.readline() 236 atos_line = self.atos.readline()
219 # A well-formed atos response looks like this: 237 # A well-formed atos response looks like this:
220 # foo(type1, type2) (in object.name) (filename.cc:80) 238 # foo(type1, type2) (in object.name) (filename.cc:80)
221 match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line) 239 match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line)
222 if DEBUG: 240 if DEBUG:
223 print 'atos_line: ', atos_line 241 print('atos_line: ', atos_line)
224 if match: 242 if match:
225 function_name = match.group(1) 243 function_name = match.group(1)
226 function_name = re.sub('\(.*?\)', '', function_name) 244 function_name = re.sub('\(.*?\)', '', function_name)
227 file_name = fix_filename(match.group(3)) 245 file_name = fix_filename(match.group(3))
228 return ['%s in %s %s' % (addr, function_name, file_name)] 246 return ['%s in %s %s' % (addr, function_name, file_name)]
229 else: 247 else:
230 return ['%s in %s' % (addr, atos_line)] 248 return ['%s in %s' % (addr, atos_line)]
231 249
232 250
233 # Chain several symbolizers so that if one symbolizer fails, we fall back 251 # Chain several symbolizers so that if one symbolizer fails, we fall back
(...skipping 18 matching lines...) Expand all
252 270
253 def BreakpadSymbolizerFactory(binary): 271 def BreakpadSymbolizerFactory(binary):
254 suffix = os.getenv('BREAKPAD_SUFFIX') 272 suffix = os.getenv('BREAKPAD_SUFFIX')
255 if suffix: 273 if suffix:
256 filename = binary + suffix 274 filename = binary + suffix
257 if os.access(filename, os.F_OK): 275 if os.access(filename, os.F_OK):
258 return BreakpadSymbolizer(filename) 276 return BreakpadSymbolizer(filename)
259 return None 277 return None
260 278
261 279
262 def SystemSymbolizerFactory(system, addr, binary): 280 def SystemSymbolizerFactory(system, addr, binary, arch):
263 if system == 'Darwin': 281 if system == 'Darwin':
264 return DarwinSymbolizer(addr, binary) 282 return DarwinSymbolizer(addr, binary, arch)
265 elif system == 'Linux': 283 elif system == 'Linux' or system == 'FreeBSD':
266 return Addr2LineSymbolizer(binary) 284 return Addr2LineSymbolizer(binary)
267 285
268 286
269 class BreakpadSymbolizer(Symbolizer): 287 class BreakpadSymbolizer(Symbolizer):
270 def __init__(self, filename): 288 def __init__(self, filename):
271 super(BreakpadSymbolizer, self).__init__() 289 super(BreakpadSymbolizer, self).__init__()
272 self.filename = filename 290 self.filename = filename
273 lines = file(filename).readlines() 291 lines = file(filename).readlines()
274 self.files = [] 292 self.files = []
275 self.symbols = {} 293 self.symbols = {}
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 return None 345 return None
328 346
329 def symbolize(self, addr, binary, offset): 347 def symbolize(self, addr, binary, offset):
330 if self.binary != binary: 348 if self.binary != binary:
331 return None 349 return None
332 res = self.get_sym_file_line(int(offset, 16)) 350 res = self.get_sym_file_line(int(offset, 16))
333 if res: 351 if res:
334 function_name, file_name, line_no = res 352 function_name, file_name, line_no = res
335 result = ['%s in %s %s:%d' % ( 353 result = ['%s in %s %s:%d' % (
336 addr, function_name, file_name, line_no)] 354 addr, function_name, file_name, line_no)]
337 print result 355 print(result)
338 return result 356 return result
339 else: 357 else:
340 return None 358 return None
341 359
342 360
343 class SymbolizationLoop(object): 361 class SymbolizationLoop(object):
344 def __init__(self, binary_name_filter=None, dsym_hint_producer=None): 362 def __init__(self, binary_name_filter=None, dsym_hint_producer=None):
345 if sys.platform == 'win32': 363 if sys.platform == 'win32':
346 # ASan on Windows uses dbghelp.dll to symbolize in-process, which works 364 # ASan on Windows uses dbghelp.dll to symbolize in-process, which works
347 # even in sandboxed processes. Nothing needs to be done here. 365 # even in sandboxed processes. Nothing needs to be done here.
348 self.process_line = self.process_line_echo 366 self.process_line = self.process_line_echo
349 else: 367 else:
350 # Used by clients who may want to supply a different binary name. 368 # Used by clients who may want to supply a different binary name.
351 # E.g. in Chrome several binaries may share a single .dSYM. 369 # E.g. in Chrome several binaries may share a single .dSYM.
352 self.binary_name_filter = binary_name_filter 370 self.binary_name_filter = binary_name_filter
353 self.dsym_hint_producer = dsym_hint_producer 371 self.dsym_hint_producer = dsym_hint_producer
354 self.system = os.uname()[0] 372 self.system = os.uname()[0]
355 if self.system not in ['Linux', 'Darwin', 'FreeBSD']: 373 if self.system not in ['Linux', 'Darwin', 'FreeBSD']:
356 raise Exception('Unknown system') 374 raise Exception('Unknown system')
357 self.llvm_symbolizers = {} 375 self.llvm_symbolizers = {}
358 self.last_llvm_symbolizer = None 376 self.last_llvm_symbolizer = None
359 self.dsym_hints = set([]) 377 self.dsym_hints = set([])
360 self.frame_no = 0 378 self.frame_no = 0
361 self.process_line = self.process_line_posix 379 self.process_line = self.process_line_posix
362 380
363 def symbolize_address(self, addr, binary, offset): 381 def symbolize_address(self, addr, binary, offset, arch):
364 # On non-Darwin (i.e. on platforms without .dSYM debug info) always use 382 # On non-Darwin (i.e. on platforms without .dSYM debug info) always use
365 # a single symbolizer binary. 383 # a single symbolizer binary.
366 # On Darwin, if the dsym hint producer is present: 384 # On Darwin, if the dsym hint producer is present:
367 # 1. check whether we've seen this binary already; if so, 385 # 1. check whether we've seen this binary already; if so,
368 # use |llvm_symbolizers[binary]|, which has already loaded the debug 386 # use |llvm_symbolizers[binary]|, which has already loaded the debug
369 # info for this binary (might not be the case for 387 # info for this binary (might not be the case for
370 # |last_llvm_symbolizer|); 388 # |last_llvm_symbolizer|);
371 # 2. otherwise check if we've seen all the hints for this binary already; 389 # 2. otherwise check if we've seen all the hints for this binary already;
372 # if so, reuse |last_llvm_symbolizer| which has the full set of hints; 390 # if so, reuse |last_llvm_symbolizer| which has the full set of hints;
373 # 3. otherwise create a new symbolizer and pass all currently known 391 # 3. otherwise create a new symbolizer and pass all currently known
374 # .dSYM hints to it. 392 # .dSYM hints to it.
375 if not binary in self.llvm_symbolizers: 393 result = None
376 use_new_symbolizer = True 394 if not force_system_symbolizer:
377 if self.system == 'Darwin' and self.dsym_hint_producer: 395 if not binary in self.llvm_symbolizers:
378 dsym_hints_for_binary = set(self.dsym_hint_producer(binary)) 396 use_new_symbolizer = True
379 use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints) 397 if self.system == 'Darwin' and self.dsym_hint_producer:
380 self.dsym_hints |= dsym_hints_for_binary 398 dsym_hints_for_binary = set(self.dsym_hint_producer(binary))
381 if self.last_llvm_symbolizer and not use_new_symbolizer: 399 use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)
400 self.dsym_hints |= dsym_hints_for_binary
401 if self.last_llvm_symbolizer and not use_new_symbolizer:
402 self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
403 else:
404 self.last_llvm_symbolizer = LLVMSymbolizerFactory(
405 self.system, arch, self.dsym_hints)
382 self.llvm_symbolizers[binary] = self.last_llvm_symbolizer 406 self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
383 else: 407 # Use the chain of symbolizers:
384 self.last_llvm_symbolizer = LLVMSymbolizerFactory( 408 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
385 self.system, guess_arch(addr), self.dsym_hints) 409 # (fall back to next symbolizer if the previous one fails).
386 self.llvm_symbolizers[binary] = self.last_llvm_symbolizer 410 if not binary in symbolizers:
387 # Use the chain of symbolizers: 411 symbolizers[binary] = ChainSymbolizer(
388 # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos 412 [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
389 # (fall back to next symbolizer if the previous one fails). 413 result = symbolizers[binary].symbolize(addr, binary, offset)
390 if not binary in symbolizers: 414 else:
391 symbolizers[binary] = ChainSymbolizer( 415 symbolizers[binary] = ChainSymbolizer([])
392 [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
393 result = symbolizers[binary].symbolize(addr, binary, offset)
394 if result is None: 416 if result is None:
417 if not allow_system_symbolizer:
418 raise Exception('Failed to launch or use llvm-symbolizer.')
395 # Initialize system symbolizer only if other symbolizers failed. 419 # Initialize system symbolizer only if other symbolizers failed.
396 symbolizers[binary].append_symbolizer( 420 symbolizers[binary].append_symbolizer(
397 SystemSymbolizerFactory(self.system, addr, binary)) 421 SystemSymbolizerFactory(self.system, addr, binary, arch))
398 result = symbolizers[binary].symbolize(addr, binary, offset) 422 result = symbolizers[binary].symbolize(addr, binary, offset)
399 # The system symbolizer must produce some result. 423 # The system symbolizer must produce some result.
400 assert result 424 assert result
401 return result 425 return result
402 426
403 def get_symbolized_lines(self, symbolized_lines): 427 def get_symbolized_lines(self, symbolized_lines):
404 if not symbolized_lines: 428 if not symbolized_lines:
405 return [self.current_line] 429 return [self.current_line]
406 else: 430 else:
407 result = [] 431 result = []
408 for symbolized_frame in symbolized_lines: 432 for symbolized_frame in symbolized_lines:
409 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri p())) 433 result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstri p()))
410 self.frame_no += 1 434 self.frame_no += 1
411 return result 435 return result
412 436
413 def process_logfile(self): 437 def process_logfile(self):
414 self.frame_no = 0 438 self.frame_no = 0
415 for line in logfile: 439 for line in logfile:
416 processed = self.process_line(line) 440 processed = self.process_line(line)
417 print '\n'.join(processed) 441 print('\n'.join(processed))
418 442
419 def process_line_echo(self, line): 443 def process_line_echo(self, line):
420 return [line.rstrip()] 444 return [line.rstrip()]
421 445
422 def process_line_posix(self, line): 446 def process_line_posix(self, line):
423 self.current_line = line.rstrip() 447 self.current_line = line.rstrip()
424 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) 448 #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
425 stack_trace_line_format = ( 449 stack_trace_line_format = (
426 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)') 450 '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)')
427 match = re.match(stack_trace_line_format, line) 451 match = re.match(stack_trace_line_format, line)
428 if not match: 452 if not match:
429 return [self.current_line] 453 return [self.current_line]
430 if DEBUG: 454 if DEBUG:
431 print line 455 print(line)
432 _, frameno_str, addr, binary, offset = match.groups() 456 _, frameno_str, addr, binary, offset = match.groups()
457 arch = ""
458 # Arch can be embedded in the filename, e.g.: "libabc.dylib:x86_64h"
459 colon_pos = binary.rfind(":")
460 if colon_pos != -1:
461 maybe_arch = binary[colon_pos+1:]
462 if is_valid_arch(maybe_arch):
463 arch = maybe_arch
464 binary = binary[0:colon_pos]
465 if arch == "":
466 arch = guess_arch(addr)
433 if frameno_str == '0': 467 if frameno_str == '0':
434 # Assume that frame #0 is the first frame of new stack trace. 468 # Assume that frame #0 is the first frame of new stack trace.
435 self.frame_no = 0 469 self.frame_no = 0
436 original_binary = binary 470 original_binary = binary
437 if self.binary_name_filter: 471 if self.binary_name_filter:
438 binary = self.binary_name_filter(binary) 472 binary = self.binary_name_filter(binary)
439 symbolized_line = self.symbolize_address(addr, binary, offset) 473 symbolized_line = self.symbolize_address(addr, binary, offset, arch)
440 if not symbolized_line: 474 if not symbolized_line:
441 if original_binary != binary: 475 if original_binary != binary:
442 symbolized_line = self.symbolize_address(addr, binary, offset) 476 symbolized_line = self.symbolize_address(addr, binary, offset, arch)
443 return self.get_symbolized_lines(symbolized_line) 477 return self.get_symbolized_lines(symbolized_line)
444 478
445 479
446 if __name__ == '__main__': 480 if __name__ == '__main__':
447 parser = argparse.ArgumentParser( 481 parser = argparse.ArgumentParser(
448 formatter_class=argparse.RawDescriptionHelpFormatter, 482 formatter_class=argparse.RawDescriptionHelpFormatter,
449 description='ASan symbolization script', 483 description='ASan symbolization script',
450 epilog='Example of use:\n' 484 epilog='Example of use:\n'
451 'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" ' 485 'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" '
452 '-s "$HOME/SymbolFiles" < asan.log') 486 '-s "$HOME/SymbolFiles" < asan.log')
453 parser.add_argument('path_to_cut', nargs='*', 487 parser.add_argument('path_to_cut', nargs='*',
454 help='pattern to be cut from the result file path ') 488 help='pattern to be cut from the result file path ')
455 parser.add_argument('-d','--demangle', action='store_true', 489 parser.add_argument('-d','--demangle', action='store_true',
456 help='demangle function names') 490 help='demangle function names')
457 parser.add_argument('-s', metavar='SYSROOT', 491 parser.add_argument('-s', metavar='SYSROOT',
458 help='set path to sysroot for sanitized binaries') 492 help='set path to sysroot for sanitized binaries')
459 parser.add_argument('-c', metavar='CROSS_COMPILE', 493 parser.add_argument('-c', metavar='CROSS_COMPILE',
460 help='set prefix for binutils') 494 help='set prefix for binutils')
461 parser.add_argument('-l','--logfile', default=sys.stdin, 495 parser.add_argument('-l','--logfile', default=sys.stdin,
462 type=argparse.FileType('r'), 496 type=argparse.FileType('r'),
463 help='set log file name to parse, default is stdin') 497 help='set log file name to parse, default is stdin')
498 parser.add_argument('--force-system-symbolizer', action='store_true',
499 help='don\'t use llvm-symbolizer')
464 args = parser.parse_args() 500 args = parser.parse_args()
465 if args.path_to_cut: 501 if args.path_to_cut:
466 fix_filename_patterns = args.path_to_cut 502 fix_filename_patterns = args.path_to_cut
467 if args.demangle: 503 if args.demangle:
468 demangle = True 504 demangle = True
469 if args.s: 505 if args.s:
470 binary_name_filter = sysroot_path_filter 506 binary_name_filter = sysroot_path_filter
471 sysroot_path = args.s 507 sysroot_path = args.s
472 if args.c: 508 if args.c:
473 binutils_prefix = args.c 509 binutils_prefix = args.c
474 if args.logfile: 510 if args.logfile:
475 logfile = args.logfile 511 logfile = args.logfile
476 else: 512 else:
477 logfile = sys.stdin 513 logfile = sys.stdin
514 if args.force_system_symbolizer:
515 force_system_symbolizer = True
516 if force_system_symbolizer:
517 assert(allow_system_symbolizer)
478 loop = SymbolizationLoop(binary_name_filter) 518 loop = SymbolizationLoop(binary_name_filter)
479 loop.process_logfile() 519 loop.process_logfile()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698