diff options
author | Kostya Serebryany <kcc@google.com> | 2011-11-30 01:07:02 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2011-11-30 01:07:02 +0000 |
commit | 019b76f5fd166e0ee07341d509c66ea09a8e7e56 (patch) | |
tree | 3e997bfbb262b869b64fbd8ba2f5d2a6e6378a9b /compiler-rt/lib/asan/scripts/asan_symbolize.py | |
parent | 71944203de65adf42c9fa9db7c4bd2b3c83ade1e (diff) | |
download | bcm5719-llvm-019b76f5fd166e0ee07341d509c66ea09a8e7e56.tar.gz bcm5719-llvm-019b76f5fd166e0ee07341d509c66ea09a8e7e56.zip |
AddressSanitizer run-time library. Not yet integrated with the compiler-rt build system, but can be built using the old makefile. See details in README.txt
llvm-svn: 145463
Diffstat (limited to 'compiler-rt/lib/asan/scripts/asan_symbolize.py')
-rwxr-xr-x | compiler-rt/lib/asan/scripts/asan_symbolize.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/scripts/asan_symbolize.py b/compiler-rt/lib/asan/scripts/asan_symbolize.py new file mode 100755 index 00000000000..80b59272516 --- /dev/null +++ b/compiler-rt/lib/asan/scripts/asan_symbolize.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +import os +import re +import sys +import string +import subprocess + +pipes = {} + +def patch_address(frameno, addr_s): + ''' Subtracts 1 or 2 from the top frame's address. + Top frame is normally the return address from asan_report* + call, which is not expected to return at all. Because of that, this + address often belongs to the next source code line, or even to a different + function. ''' + if frameno == '0': + addr = int(addr_s, 16) + if os.uname()[4].startswith('arm'): + # Cancel the Thumb bit + addr = addr & (~1) + addr -= 1 + return hex(addr) + return addr_s + +# TODO(glider): need some refactoring here +def symbolize_addr2line(line): + #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) + match = re.match('^( *#([0-9]+) *0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)', line) + if match: + frameno = match.group(2) + binary = match.group(3) + addr = match.group(4) + addr = patch_address(frameno, addr) + if not pipes.has_key(binary): + pipes[binary] = subprocess.Popen(["addr2line", "-f", "-e", binary], + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + p = pipes[binary] + try: + print >>p.stdin, addr + function_name = p.stdout.readline().rstrip() + file_name = p.stdout.readline().rstrip() + except: + function_name = "" + file_name = "" + for path_to_cut in sys.argv[1:]: + file_name = re.sub(".*" + path_to_cut, "", file_name) + file_name = re.sub(".*asan_[a-z_]*.cc:[0-9]*", "_asan_rtl_", file_name) + file_name = re.sub(".*crtstuff.c:0", "???:0", file_name) + + print match.group(1), "in", function_name, file_name + else: + print line.rstrip() + +def symbolize_atos(line): + #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) + match = re.match('^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)', line) + if match: + #print line + prefix = match.group(1) + frameno = match.group(2) + addr = match.group(3) + binary = match.group(4) + offset = match.group(5) + addr = patch_address(frameno, addr) + load_addr = int(addr, 16) - int(offset, 16) + if not pipes.has_key(binary): + #print "atos -o %s -l %s" % (binary, hex(load_addr)) + pipes[binary] = subprocess.Popen(["atos", "-o", binary], + stdin=subprocess.PIPE, stdout=subprocess.PIPE,) + p = pipes[binary] + # TODO(glider): how to tell if the address is absolute? + if ".app/" in binary and not ".framework" in binary: + print >>p.stdin, "%s" % addr + else: + print >>p.stdin, "%s" % offset + # TODO(glider): it's more efficient to make a batch atos run for each binary. + p.stdin.close() + atos_line = p.stdout.readline().rstrip() + del pipes[binary] + + print "%s%s in %s" % (prefix, addr, atos_line) + else: + print line.rstrip() + +system = os.uname()[0] +if system in ['Linux', 'Darwin']: + for line in sys.stdin: + if system == 'Linux': + symbolize_addr2line(line) + elif system == 'Darwin': + symbolize_atos(line) +else: + print 'Unknown system: ', system |