Skip to content

Commit

Permalink
Merge "Fix addr2line with missing files" from Rafael
Browse files Browse the repository at this point in the history
I was still getting errors when running seastar-addr2line with missing
files. Not sure if this is because of a change in behavior in python,
but I did test this change with 2.7.

If we do need to catch IOError in some old version of python it should
be easy to add it back to this code structure.

* https://github.com/espindola/seastar espindola/addr2line-fixes:
  Avoid doing work in the destructor.
  Check for missing files in the Addr2Line constructor
  • Loading branch information
tgrabiec committed Dec 17, 2018
2 parents 1eecb36 + 4173042 commit 2e03894
Showing 1 changed file with 22 additions and 21 deletions.
43 changes: 22 additions & 21 deletions scripts/seastar-addr2line
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ class Addr2Line:
self._binary = binary
self._addr2line = subprocess.Popen(["addr2line", "-Cfpia", "-e", self._binary], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)

# If a library doesn't exist in a particular path, addr2line
# will just exit. We need to be robust against that. We
# can't just wait on self._addr2line since there is no
# guarantee on what timeout is sufficient.
self._addr2line.stdin.write('\n')
self._addr2line.stdin.flush()
res = self._addr2line.stdout.readline()
self._missing = res == ''

def _read_resolved_address(self):
res = self._addr2line.stdout.readline()
# remove the address
Expand All @@ -41,24 +50,13 @@ class Addr2Line:
return res

def __call__(self, address):
# If a library doesn't exist in a particular path, addr2line will just
# return an IOError, so we need to be robust against that.
#
# It would be cleaner to already know that in advance in the constructor,
# but unfortunately the process won't really exit with a return code until
# we try to pipe something to it - so we wrap the decoding code in a
# try/except block.
#
# Instead of an exception we print the address and library name and
# move on.
try:
# print two lines to force addr2line to output a dummy
# line which we can look for in _read_address
self._addr2line.stdin.write(address + '\n\n')
self._addr2line.stdin.flush()
return self._read_resolved_address()
except IOError:
if self._missing:
return " ".join([self._binary, address, '\n'])
# print two lines to force addr2line to output a dummy
# line which we can look for in _read_address
self._addr2line.stdin.write(address + '\n\n')
self._addr2line.stdin.flush()
return self._read_resolved_address()

class BacktraceResolver(object):
object_address_re = re.compile('^.*?(((/[^/]+)+)\+)?(0x[0-9a-f]+)\W*$')
Expand All @@ -78,7 +76,10 @@ class BacktraceResolver(object):
self._known_modules[module] = Addr2Line(module)
return self._known_modules[module]

def __del__(self):
def __enter__(self):
return self

def __exit__(self, type, value, tb):
self._print_current_backtrace()

def _print_resolved_address(self, module, address):
Expand Down Expand Up @@ -237,6 +238,6 @@ else:
else:
lines = sys.stdin

resolve = BacktraceResolver(args.executable, args.before, args.verbose)
for line in lines:
resolve(line)
with BacktraceResolver(args.executable, args.before, args.verbose) as resolve:
for line in lines:
resolve(line)

0 comments on commit 2e03894

Please sign in to comment.