Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions tools/stack_decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# contain backtrace output extract the address and call add2line to get the file
# and line information. Output appended to end of original backtrace line. Output
# any nonmatching lines unmodified. End when EOF received.
def decode_stacktrace_log(object_file, input_source):
def decode_stacktrace_log(object_file, input_source, address_offset=0):
traces = {}
# Match something like:
# [backtrace] [bazel-out/local-dbg/bin/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:84]
Expand All @@ -45,9 +45,14 @@ def decode_stacktrace_log(object_file, input_source):
stackaddr_match = asan_re.search(line)
if stackaddr_match:
address = stackaddr_match.groups()[0]
if address_offset != 0:
address = hex(int(address, 16) - address_offset)
file_and_line_number = run_addr2line(object_file, address)
file_and_line_number = trim_proc_cwd(file_and_line_number)
sys.stdout.write("%s %s" % (line.strip(), file_and_line_number))
if address_offset != 0:
sys.stdout.write("%s->[%s] %s" % (line.strip(), address, file_and_line_number))
else:
sys.stdout.write("%s %s" % (line.strip(), file_and_line_number))
continue
else:
# Pass through print all other log lines:
Expand All @@ -72,6 +77,27 @@ def trim_proc_cwd(file_and_line_number):
return re.sub(trim_regex, '', file_and_line_number)


# Execute pmap with a pid to calculate the addr offset
#
# Returns list of extended process memory information.
def run_pmap(pid):
return subprocess.check_output(['pmap', '-qX', str(pid)]).decode('utf-8')[1:]


# Find the virtual address offset of the process. This may be needed due ASLR.
#
# Returns the virtual address offset as an integer, or 0 if unable to determine.
def find_address_offset(pid):
try:
proc_memory = run_pmap(pid)
match = re.search(r'([a-f0-9]+)\s+r-xp', proc_memory)
if match is None:
return 0
return int(match.group(1), 16)
except (subprocess.CalledProcessError, PermissionError):
return 0


if __name__ == "__main__":
if len(sys.argv) > 2 and sys.argv[1] == '-s':
decode_stacktrace_log(sys.argv[2], sys.stdin)
Expand All @@ -81,7 +107,8 @@ def trim_proc_cwd(file_and_line_number):
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
decode_stacktrace_log(sys.argv[1], rununder.stdout)
offset = find_address_offset(rununder.pid)
decode_stacktrace_log(sys.argv[1], rununder.stdout, offset)
rununder.wait()
sys.exit(rununder.returncode) # Pass back test pass/fail result
else:
Expand Down