forked from OSchip/llvm-project
[ASan] Cache atos processes to make Darwin symbolication faster.
Patch by Jesse Ruderman<jruderman@gmail.com> llvm-svn: 185325
This commit is contained in:
parent
6b5a492091
commit
0fde89f2aa
|
@ -10,9 +10,11 @@
|
|||
import bisect
|
||||
import getopt
|
||||
import os
|
||||
import pty
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import termios
|
||||
|
||||
llvm_symbolizer = None
|
||||
symbolizers = {}
|
||||
|
@ -135,6 +137,33 @@ class Addr2LineSymbolizer(Symbolizer):
|
|||
return ['%s in %s %s' % (addr, function_name, file_name)]
|
||||
|
||||
|
||||
class UnbufferedLineConverter(object):
|
||||
"""
|
||||
Wrap a child process that responds to each line of input with one line of
|
||||
output. Uses pty to trick the child into providing unbuffered output.
|
||||
"""
|
||||
def __init__(self, args):
|
||||
pid, fd = pty.fork()
|
||||
if pid == 0:
|
||||
# We're the child. Transfer control to command.
|
||||
os.execvp(args[0], args)
|
||||
else:
|
||||
# Disable echoing.
|
||||
attr = termios.tcgetattr(fd)
|
||||
attr[3] = attr[3] & ~termios.ECHO
|
||||
termios.tcsetattr(fd, termios.TCSANOW, attr)
|
||||
# Set up a file()-like interface to the child process
|
||||
self.r = os.fdopen(fd, "r", 1)
|
||||
self.w = os.fdopen(os.dup(fd), "w", 1)
|
||||
|
||||
def convert(self, line):
|
||||
self.w.write(line + "\n")
|
||||
return self.readline()
|
||||
|
||||
def readline(self):
|
||||
return self.r.readline().rstrip()
|
||||
|
||||
|
||||
class DarwinSymbolizer(Symbolizer):
|
||||
def __init__(self, addr, binary):
|
||||
super(DarwinSymbolizer, self).__init__()
|
||||
|
@ -144,28 +173,21 @@ class DarwinSymbolizer(Symbolizer):
|
|||
self.arch = 'x86_64'
|
||||
else:
|
||||
self.arch = 'i386'
|
||||
self.pipe = None
|
||||
|
||||
def write_addr_to_pipe(self, offset):
|
||||
print >> self.pipe.stdin, '0x%x' % int(offset, 16)
|
||||
self.open_atos()
|
||||
|
||||
def open_atos(self):
|
||||
if DEBUG:
|
||||
print 'atos -o %s -arch %s' % (self.binary, self.arch)
|
||||
cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
|
||||
self.pipe = subprocess.Popen(cmdline,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
self.atos = UnbufferedLineConverter(cmdline)
|
||||
|
||||
def symbolize(self, addr, binary, offset):
|
||||
"""Overrides Symbolizer.symbolize."""
|
||||
if self.binary != binary:
|
||||
return None
|
||||
self.open_atos()
|
||||
self.write_addr_to_pipe(offset)
|
||||
self.pipe.stdin.close()
|
||||
atos_line = self.pipe.stdout.readline().rstrip()
|
||||
atos_line = self.atos.convert('0x%x' % int(offset, 16))
|
||||
while "got symbolicator for" in atos_line:
|
||||
atos_line = self.atos.readline()
|
||||
# A well-formed atos response looks like this:
|
||||
# foo(type1, type2) (in object.name) (filename.cc:80)
|
||||
match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line)
|
||||
|
|
Loading…
Reference in New Issue