Skip to content

Commit

Permalink
Review comments. Round 5. Integration test for symbolicate-linux-fatal.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmilos committed Sep 8, 2016
1 parent 900674f commit d101465
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 58 deletions.
23 changes: 23 additions & 0 deletions test/Runtime/linux-fatal-backtrace.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: %target-build-swift %s -o %t/a.out
// RUN: not --crash %t/a.out 2>&1 | PYTHONPATH=%lldb-python-path %utils/symbolicate-linux-fatal %t/a.out - | %utils/backtrace-check -u

// REQUIRES: executable_test
// REQUIRES: OS=linux-gnu
// REQUIRES: lldb

// Backtraces are not emitted when optimizations are enabled. This test can not
// run when optimizations are enabled.
// REQUIRES: swift_test_mode_optimize_none

func funcB() {
fatalError("linux-fatal-backtrace");
}

func funcA() {
funcB();
}

print("bla")
funcA()
9 changes: 7 additions & 2 deletions test/lit.site.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import os
import platform
import sys

## Autogenerated by Swift configuration.
# Do not edit!
config.llvm_src_root = "@LLVM_MAIN_SRC_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
Expand Down Expand Up @@ -76,6 +74,13 @@ if "@CMAKE_GENERATOR@" == "Xcode":
config.environment['PATH'] = \
os.path.pathsep.join((xcode_bin_dir, config.environment['PATH']))

if "@LLDB_ENABLE@" == "TRUE":
config.available_features.add('lldb')
for root, dirs, files in os.walk("@LLDB_BUILD_DIR@"):
if root.endswith("site-packages"):
config.substitutions.append(('%lldb-python-path', root))
break

# Let the main config do the real work.
if config.test_exec_root is None:
config.test_exec_root = os.path.dirname(os.path.realpath(__file__))
Expand Down
96 changes: 58 additions & 38 deletions utils/backtrace-check
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,64 @@
# 11 libswiftCore.dylib 0x000000000dce84d0l _fatalErrorMessage(StaticString,
# StaticString, StaticString, UInt, flags : UInt32) -> () + 444

import argparse
import re
import sys

TARGET_RE = re.compile(
"(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
"(?P<routine>[^+]+) [+] (?P<offset>\d+)")

lines = sys.stdin.readlines()

found_stack_trace_start = False
found_stack_trace_entry = False
for l in lines:
l = l.rstrip("\n")

# First see if we found the start of our stack trace start. If so, set the
# found stack trace flag and continue.
if l == "Current stack trace:":
assert(not found_stack_trace_start)
found_stack_trace_start = True
continue

# Otherwise, if we have not yet found the stack trace start, continue. We
# need to find the stack trace start line.
if not found_stack_trace_start:
continue

# Ok, we are in the middle of matching a stack trace entry.
m = TARGET_RE.match(l)
# If we fail to match, we have exited the stack trace entry region
if m is None:
break
# At this point, we know that we have some sort of match.
found_stack_trace_entry = True
print("Stack Trace Entry:")
print("\tIndex: '%(index)s'\n\tObject File: '%(object)s'\n\tAddress: "
"'%(address)s'\n\tRoutine: '%(routine)s'\n\tOffset: '%(offset)s'"
"\n" % m.groupdict())

# Once we have processed all of the lines, make sure that we found at least one
# stack trace entry.
assert(found_stack_trace_entry)

def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Checks that a stacktrace dump follows canonical
formatting.""")
parser.add_argument(
"-u", "--check-unavailable", action='store_true',
help="Checks if any symbols were unavailable")
args = parser.parse_args()

TARGET_RE = re.compile(
"(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
"(?P<routine>[^+]+) [+] (?P<offset>\d+)")

lines = sys.stdin.readlines()

found_stack_trace_start = False
found_stack_trace_entry = False
for l in lines:
l = l.rstrip("\n")

# First see if we found the start of our stack trace start. If so, set
# the found stack trace flag and continue.
if l == "Current stack trace:":
assert(not found_stack_trace_start)
found_stack_trace_start = True
continue

# Otherwise, if we have not yet found the stack trace start, continue.
# We need to find the stack trace start line.
if not found_stack_trace_start:
continue

# Ok, we are in the middle of matching a stack trace entry.
m = TARGET_RE.match(l)
# If we fail to match, we have exited the stack trace entry region
if m is None:
break

# At this point, we know that we have some sort of match.
found_stack_trace_entry = True
print("Stack Trace Entry:")
print("\tIndex: '%(index)s'\n\tObject File: '%(object)s'\n\tAddress: "
"'%(address)s'\n\tRoutine: '%(routine)s'\n\tOffset: '%(offset)s'"
"\n" % m.groupdict())

# Check for unavailable symbols, if that was requested.
if args.check_unavailable:
assert("unavailable" not in m.group("routine"))

# Once we have processed all of the lines, make sure that we found at least
# one stack trace entry.
assert(found_stack_trace_entry)

if __name__ == '__main__':
main()
21 changes: 21 additions & 0 deletions utils/build-script-impl
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,18 @@ if [[ ! "${SKIP_BUILD_SWIFTPM}" ]] ; then
PRODUCTS=("${PRODUCTS[@]}" swiftpm)
fi

# Checks if a given product is enabled (i.e. part of $PRODUCS array)
function contains_product() {
local current_product
for current_product in "$PRODUCTS"; do
if [[ "$current_product" == "$1" ]]; then
return 1
fi
done
return 0
}


# get_host_specific_variable(host, name)
#
# Get the value of a host-specific variable expected to have been passed by the
Expand Down Expand Up @@ -2039,6 +2051,15 @@ for host in "${ALL_HOSTS[@]}"; do
)
fi

if contains_product "lldb" ; then
lldb_build_dir=$(build_directory ${host} lldb)
cmake_options=(
"${cmake_options[@]}"
-DLLDB_ENABLE:BOOL=TRUE
-DLLDB_BUILD_DIR:STRING="${lldb_build_dir}"
)
fi

build_targets=(all "${SWIFT_STDLIB_TARGETS[@]}")
if [[ $(true_false "${build_perf_testsuite_this_time}") == "TRUE" ]]; then
native_swift_tools_path="$(build_directory_bin ${LOCAL_HOST} swift)"
Expand Down
38 changes: 22 additions & 16 deletions utils/symbolicate-linux-fatal
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ from __future__ import print_function

import argparse
import subprocess
import sys

import lldb

Expand Down Expand Up @@ -84,16 +85,19 @@ def process_stack(binary, dyn_libs, stack):
memmap[dynlib_path] = dynlib_baseaddr
else:
framePC = int(stack_tokens[2], 16) + int(stack_tokens[-1], 10)
full_stack.append({"line": line, "framePC": framePC})
full_stack.append(
{"line": line, "framePC": framePC, "dynlib_fname": dynlib_fname})

lldb_target = create_lldb_target(binary, memmap)
frame_idx = 0
for frame in full_stack:
use_orig_line = True
frame_addr = frame["framePC"]
dynlib_fname = frame["dynlib_fname"]
so_addr = lldb_target.ResolveLoadAddress(frame_addr-1)
sym_ctx = so_addr.GetSymbolContext(lldb.eSymbolContextEverything)
frame_fragment = "{0: <4d} 0x{1:016x}".format(frame_idx, frame_addr)
frame_fragment = "{0: <4d} {1:20s} 0x{2:016x}".format(
frame_idx, dynlib_fname, frame_addr)
symbol = sym_ctx.GetSymbol()
if symbol.IsValid():
symbol_base = symbol.GetStartAddress().GetLoadAddress(lldb_target)
Expand Down Expand Up @@ -127,7 +131,10 @@ def main():
args = parser.parse_args()

binary = args.binary
logfile = args.log
if args.log == "-":
logfile = sys.stdin
else:
logfile = open(args.log, 'rU')

lddoutput = subprocess.check_output(
['ldd', binary], stderr=subprocess.STDOUT)
Expand All @@ -136,19 +143,18 @@ def main():
instack = False
stackidx = 0
stack = []
with open(logfile, 'rU') as f:
for line in f:
if instack and line.startswith(str(stackidx)):
stack.append(line)
stackidx = stackidx + 1
else:
instack = False
stackidx = 0
process_stack(binary, dyn_libs, stack)
stack = []
print(line.rstrip())
if line.startswith("Current stack trace:"):
instack = True
for line in logfile:
if instack and line.startswith(str(stackidx)):
stack.append(line)
stackidx = stackidx + 1
else:
instack = False
stackidx = 0
process_stack(binary, dyn_libs, stack)
stack = []
print(line.rstrip())
if line.startswith("Current stack trace:"):
instack = True
process_stack(binary, dyn_libs, stack)


Expand Down
2 changes: 0 additions & 2 deletions validation-test/lit.site.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import sys
import platform

## Autogenerated by Swift configuration.
# Do not edit!
config.llvm_src_root = "@LLVM_MAIN_SRC_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
Expand Down

0 comments on commit d101465

Please sign in to comment.