[llvm-commits] [compiler-rt] r149064 - /compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py

Alexander Potapenko glider at google.com
Thu Jan 26 09:06:50 PST 2012


Author: glider
Date: Thu Jan 26 11:06:50 2012
New Revision: 149064

URL: http://llvm.org/viewvc/llvm-project?rev=149064&view=rev
Log:
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).

Modified:
    compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py

Modified: compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py?rev=149064&r1=149063&r2=149064&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py (original)
+++ compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py Thu Jan 26 11:06:50 2012
@@ -14,6 +14,8 @@
 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 @@
     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 @@
     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 @@
     #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()
 





More information about the llvm-commits mailing list