diff options
author | Alexander Potapenko <glider@google.com> | 2012-01-26 17:06:50 +0000 |
---|---|---|
committer | Alexander Potapenko <glider@google.com> | 2012-01-26 17:06:50 +0000 |
commit | 02a71626e3765502f59e1be769ebabb5b944bb3f (patch) | |
tree | d999279ebeeaf368d899244f74059bf2bb50c69a /compiler-rt/lib/asan/scripts/asan_symbolize.py | |
parent | 98f0c713d994a55d5fed21717daff776179400d2 (diff) | |
download | bcm5719-llvm-02a71626e3765502f59e1be769ebabb5b944bb3f.tar.gz bcm5719-llvm-02a71626e3765502f59e1be769ebabb5b944bb3f.zip |
More accurate atos execution which depends on the file type (EXECUTE, DYLIB) of the binary.
More Linux-like output on Mac (to match more output tests).
llvm-svn: 149064
Diffstat (limited to 'compiler-rt/lib/asan/scripts/asan_symbolize.py')
-rwxr-xr-x | compiler-rt/lib/asan/scripts/asan_symbolize.py | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/compiler-rt/lib/asan/scripts/asan_symbolize.py b/compiler-rt/lib/asan/scripts/asan_symbolize.py index 154e1f2994b..357593d532b 100755 --- a/compiler-rt/lib/asan/scripts/asan_symbolize.py +++ b/compiler-rt/lib/asan/scripts/asan_symbolize.py @@ -14,6 +14,8 @@ import string import subprocess pipes = {} +filetypes = {} +DEBUG=False def patch_address(frameno, addr_s): ''' Subtracts 1 or 2 from the top frame's address. @@ -30,6 +32,15 @@ def patch_address(frameno, addr_s): return hex(addr) return addr_s + +def fix_filename(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) + return file_name + + # TODO(glider): need some refactoring here def symbolize_addr2line(line): #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) @@ -50,15 +61,25 @@ def symbolize_addr2line(line): 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) + file_name = fix_filename(file_name) print match.group(1), "in", function_name, file_name else: print line.rstrip() + +def get_macho_filetype(binary): + if not filetypes.has_key(binary): + otool_pipe = subprocess.Popen(["otool", "-Vh", binary], + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + otool_line = "".join(otool_pipe.stdout.readlines()) + for t in ["DYLIB", "EXECUTE"]: + if t in otool_line: + filetypes[binary] = t + otool_pipe.stdin.close() + return filetypes[binary] + + def symbolize_atos(line): #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45) match = re.match('^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)', line) @@ -66,32 +87,46 @@ def symbolize_atos(line): #print line prefix = match.group(1) frameno = match.group(2) - addr = match.group(3) + orig_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) + addr = patch_address(frameno, orig_addr) + load_addr = hex(int(orig_addr, 16) - int(offset, 16)) + filetype = get_macho_filetype(binary) + if not pipes.has_key(binary): # Guess which arch we're running. 10 = len("0x") + 8 hex digits. if len(addr) > 10: arch = "x86_64" else: arch = "i386" - #print "atos -o %s -arch %s " % (binary, arch) - pipes[binary] = subprocess.Popen(["atos", "-o", binary, "-arch", arch], + + if filetype == "DYLIB": + load_addr = "0x0" + if DEBUG: + print "atos -o %s -arch %s -l %s" % (binary, arch, load_addr) + pipes[binary] = subprocess.Popen(["atos", "-o", binary, "-arch", arch, "-l", load_addr], 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 + if filetype == "DYLIB": + print >>p.stdin, "%s" % offset else: print >>p.stdin, "%s" % addr # TODO(glider): it's more efficient to make a batch atos run for each binary. p.stdin.close() atos_line = p.stdout.readline().rstrip() + # A well-formed atos response looks like this: + # foo(type1, type2) (in object.name) (filename.cc:80) + match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line) + #print "atos_line: ", atos_line + if match: + function_name = match.group(1) + function_name = re.sub("\(.*?\)", "", function_name) + file_name = fix_filename(match.group(3)) + print "%s%s in %s %s" % (prefix, addr, function_name, file_name) + else: + print "%s%s in %s" % (prefix, addr, atos_line) del pipes[binary] - - print "%s%s in %s" % (prefix, addr, atos_line) else: print line.rstrip() |