Improve llvm-symbolizer discovery in asan_symbolize.py

llvm-svn: 202982
This commit is contained in:
Alexey Samsonov 2014-03-05 15:00:36 +00:00
parent e062e4c7eb
commit 8ad7a05bb4
2 changed files with 25 additions and 18 deletions

View File

@ -16,7 +16,6 @@ import subprocess
import sys import sys
import termios import termios
llvm_symbolizer = None
symbolizers = {} symbolizers = {}
DEBUG = False DEBUG = False
demangle = False; demangle = False;
@ -30,6 +29,12 @@ def fix_filename(file_name):
file_name = re.sub('.*crtstuff.c:0', '???:0', file_name) file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
return file_name return file_name
def GuessArch(addr):
# Guess which arch we're running. 10 = len('0x') + 8 hex digits.
if len(addr) > 10:
return 'x86_64'
else:
return 'i386'
class Symbolizer(object): class Symbolizer(object):
def __init__(self): def __init__(self):
@ -52,23 +57,27 @@ class Symbolizer(object):
class LLVMSymbolizer(Symbolizer): class LLVMSymbolizer(Symbolizer):
def __init__(self, symbolizer_path): def __init__(self, symbolizer_path, addr):
super(LLVMSymbolizer, self).__init__() super(LLVMSymbolizer, self).__init__()
self.symbolizer_path = symbolizer_path self.symbolizer_path = symbolizer_path
self.default_arch = GuessArch(addr)
self.pipe = self.open_llvm_symbolizer() self.pipe = self.open_llvm_symbolizer()
def open_llvm_symbolizer(self): def open_llvm_symbolizer(self):
if not os.path.exists(self.symbolizer_path):
return None
cmd = [self.symbolizer_path, cmd = [self.symbolizer_path,
'--use-symbol-table=true', '--use-symbol-table=true',
'--demangle=%s' % demangle, '--demangle=%s' % demangle,
'--functions=true', '--functions=true',
'--inlining=true'] '--inlining=true',
'--default-arch=%s' % self.default_arch]
if DEBUG: if DEBUG:
print ' '.join(cmd) print ' '.join(cmd)
return subprocess.Popen(cmd, stdin=subprocess.PIPE, try:
result = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE) stdout=subprocess.PIPE)
except OSError:
result = None
return result
def symbolize(self, addr, binary, offset): def symbolize(self, addr, binary, offset):
"""Overrides Symbolizer.symbolize.""" """Overrides Symbolizer.symbolize."""
@ -98,14 +107,14 @@ class LLVMSymbolizer(Symbolizer):
return result return result
def LLVMSymbolizerFactory(system): def LLVMSymbolizerFactory(system, addr):
symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH') symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')
if not symbolizer_path: if not symbolizer_path:
symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH') symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH')
if not symbolizer_path: if not symbolizer_path:
# Assume llvm-symbolizer is in PATH. # Assume llvm-symbolizer is in PATH.
symbolizer_path = 'llvm-symbolizer' symbolizer_path = 'llvm-symbolizer'
return LLVMSymbolizer(symbolizer_path) return LLVMSymbolizer(symbolizer_path, addr)
class Addr2LineSymbolizer(Symbolizer): class Addr2LineSymbolizer(Symbolizer):
@ -173,11 +182,7 @@ class DarwinSymbolizer(Symbolizer):
def __init__(self, addr, binary): def __init__(self, addr, binary):
super(DarwinSymbolizer, self).__init__() super(DarwinSymbolizer, self).__init__()
self.binary = binary self.binary = binary
# Guess which arch we're running. 10 = len('0x') + 8 hex digits. self.arch = GuessArch(addr)
if len(addr) > 10:
self.arch = 'x86_64'
else:
self.arch = 'i386'
self.open_atos() self.open_atos()
def open_atos(self): def open_atos(self):
@ -323,12 +328,14 @@ class SymbolizationLoop(object):
# E.g. in Chrome several binaries may share a single .dSYM. # E.g. in Chrome several binaries may share a single .dSYM.
self.binary_name_filter = binary_name_filter self.binary_name_filter = binary_name_filter
self.system = os.uname()[0] self.system = os.uname()[0]
if self.system in ['Linux', 'Darwin']: if self.system not in ['Linux', 'Darwin']:
self.llvm_symbolizer = LLVMSymbolizerFactory(self.system)
else:
raise Exception('Unknown system') raise Exception('Unknown system')
self.llvm_symbolizer = None
def symbolize_address(self, addr, binary, offset): def symbolize_address(self, addr, binary, offset):
# Initialize llvm-symbolizer lazily.
if not self.llvm_symbolizer:
self.llvm_symbolizer = LLVMSymbolizerFactory(self.system, addr)
# Use the chain of symbolizers: # Use the chain of symbolizers:
# Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
# (fall back to next symbolizer if the previous one fails). # (fall back to next symbolizer if the previous one fails).

View File

@ -3,7 +3,7 @@
// RUN: %clangxx_asan -O0 %p/SharedLibs/shared-lib-test-so.cc -fPIC -shared -o %t-so.so // RUN: %clangxx_asan -O0 %p/SharedLibs/shared-lib-test-so.cc -fPIC -shared -o %t-so.so
// RUN: %clangxx_asan -O0 %s -o %t // RUN: %clangxx_asan -O0 %s -o %t
// RUN: ASAN_SYMBOLIZER_PATH= not %t 2>&1 | %asan_symbolize | FileCheck %s // RUN: ASAN_OPTIONS=symbolize=0 not %t 2>&1 | %asan_symbolize | FileCheck %s
#include <dlfcn.h> #include <dlfcn.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>