Skip to content

Commit d101465

Browse files
committed
Review comments. Round 5. Integration test for symbolicate-linux-fatal.
1 parent 900674f commit d101465

File tree

6 files changed

+131
-58
lines changed

6 files changed

+131
-58
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: %target-build-swift %s -o %t/a.out
4+
// RUN: not --crash %t/a.out 2>&1 | PYTHONPATH=%lldb-python-path %utils/symbolicate-linux-fatal %t/a.out - | %utils/backtrace-check -u
5+
6+
// REQUIRES: executable_test
7+
// REQUIRES: OS=linux-gnu
8+
// REQUIRES: lldb
9+
10+
// Backtraces are not emitted when optimizations are enabled. This test can not
11+
// run when optimizations are enabled.
12+
// REQUIRES: swift_test_mode_optimize_none
13+
14+
func funcB() {
15+
fatalError("linux-fatal-backtrace");
16+
}
17+
18+
func funcA() {
19+
funcB();
20+
}
21+
22+
print("bla")
23+
funcA()

test/lit.site.cfg.in

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import os
1414
import platform
1515
import sys
1616

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

77+
if "@LLDB_ENABLE@" == "TRUE":
78+
config.available_features.add('lldb')
79+
for root, dirs, files in os.walk("@LLDB_BUILD_DIR@"):
80+
if root.endswith("site-packages"):
81+
config.substitutions.append(('%lldb-python-path', root))
82+
break
83+
7984
# Let the main config do the real work.
8085
if config.test_exec_root is None:
8186
config.test_exec_root = os.path.dirname(os.path.realpath(__file__))

utils/backtrace-check

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,64 @@
1818
# 11 libswiftCore.dylib 0x000000000dce84d0l _fatalErrorMessage(StaticString,
1919
# StaticString, StaticString, UInt, flags : UInt32) -> () + 444
2020

21+
import argparse
2122
import re
2223
import sys
2324

24-
TARGET_RE = re.compile(
25-
"(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
26-
"(?P<routine>[^+]+) [+] (?P<offset>\d+)")
27-
28-
lines = sys.stdin.readlines()
29-
30-
found_stack_trace_start = False
31-
found_stack_trace_entry = False
32-
for l in lines:
33-
l = l.rstrip("\n")
34-
35-
# First see if we found the start of our stack trace start. If so, set the
36-
# found stack trace flag and continue.
37-
if l == "Current stack trace:":
38-
assert(not found_stack_trace_start)
39-
found_stack_trace_start = True
40-
continue
41-
42-
# Otherwise, if we have not yet found the stack trace start, continue. We
43-
# need to find the stack trace start line.
44-
if not found_stack_trace_start:
45-
continue
46-
47-
# Ok, we are in the middle of matching a stack trace entry.
48-
m = TARGET_RE.match(l)
49-
# If we fail to match, we have exited the stack trace entry region
50-
if m is None:
51-
break
52-
# At this point, we know that we have some sort of match.
53-
found_stack_trace_entry = True
54-
print("Stack Trace Entry:")
55-
print("\tIndex: '%(index)s'\n\tObject File: '%(object)s'\n\tAddress: "
56-
"'%(address)s'\n\tRoutine: '%(routine)s'\n\tOffset: '%(offset)s'"
57-
"\n" % m.groupdict())
58-
59-
# Once we have processed all of the lines, make sure that we found at least one
60-
# stack trace entry.
61-
assert(found_stack_trace_entry)
25+
26+
def main():
27+
parser = argparse.ArgumentParser(
28+
formatter_class=argparse.RawDescriptionHelpFormatter,
29+
description="""Checks that a stacktrace dump follows canonical
30+
formatting.""")
31+
parser.add_argument(
32+
"-u", "--check-unavailable", action='store_true',
33+
help="Checks if any symbols were unavailable")
34+
args = parser.parse_args()
35+
36+
TARGET_RE = re.compile(
37+
"(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
38+
"(?P<routine>[^+]+) [+] (?P<offset>\d+)")
39+
40+
lines = sys.stdin.readlines()
41+
42+
found_stack_trace_start = False
43+
found_stack_trace_entry = False
44+
for l in lines:
45+
l = l.rstrip("\n")
46+
47+
# First see if we found the start of our stack trace start. If so, set
48+
# the found stack trace flag and continue.
49+
if l == "Current stack trace:":
50+
assert(not found_stack_trace_start)
51+
found_stack_trace_start = True
52+
continue
53+
54+
# Otherwise, if we have not yet found the stack trace start, continue.
55+
# We need to find the stack trace start line.
56+
if not found_stack_trace_start:
57+
continue
58+
59+
# Ok, we are in the middle of matching a stack trace entry.
60+
m = TARGET_RE.match(l)
61+
# If we fail to match, we have exited the stack trace entry region
62+
if m is None:
63+
break
64+
65+
# At this point, we know that we have some sort of match.
66+
found_stack_trace_entry = True
67+
print("Stack Trace Entry:")
68+
print("\tIndex: '%(index)s'\n\tObject File: '%(object)s'\n\tAddress: "
69+
"'%(address)s'\n\tRoutine: '%(routine)s'\n\tOffset: '%(offset)s'"
70+
"\n" % m.groupdict())
71+
72+
# Check for unavailable symbols, if that was requested.
73+
if args.check_unavailable:
74+
assert("unavailable" not in m.group("routine"))
75+
76+
# Once we have processed all of the lines, make sure that we found at least
77+
# one stack trace entry.
78+
assert(found_stack_trace_entry)
79+
80+
if __name__ == '__main__':
81+
main()

utils/build-script-impl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,18 @@ if [[ ! "${SKIP_BUILD_SWIFTPM}" ]] ; then
12401240
PRODUCTS=("${PRODUCTS[@]}" swiftpm)
12411241
fi
12421242

1243+
# Checks if a given product is enabled (i.e. part of $PRODUCS array)
1244+
function contains_product() {
1245+
local current_product
1246+
for current_product in "$PRODUCTS"; do
1247+
if [[ "$current_product" == "$1" ]]; then
1248+
return 1
1249+
fi
1250+
done
1251+
return 0
1252+
}
1253+
1254+
12431255
# get_host_specific_variable(host, name)
12441256
#
12451257
# Get the value of a host-specific variable expected to have been passed by the
@@ -2039,6 +2051,15 @@ for host in "${ALL_HOSTS[@]}"; do
20392051
)
20402052
fi
20412053

2054+
if contains_product "lldb" ; then
2055+
lldb_build_dir=$(build_directory ${host} lldb)
2056+
cmake_options=(
2057+
"${cmake_options[@]}"
2058+
-DLLDB_ENABLE:BOOL=TRUE
2059+
-DLLDB_BUILD_DIR:STRING="${lldb_build_dir}"
2060+
)
2061+
fi
2062+
20422063
build_targets=(all "${SWIFT_STDLIB_TARGETS[@]}")
20432064
if [[ $(true_false "${build_perf_testsuite_this_time}") == "TRUE" ]]; then
20442065
native_swift_tools_path="$(build_directory_bin ${LOCAL_HOST} swift)"

utils/symbolicate-linux-fatal

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ from __future__ import print_function
2626

2727
import argparse
2828
import subprocess
29+
import sys
2930

3031
import lldb
3132

@@ -84,16 +85,19 @@ def process_stack(binary, dyn_libs, stack):
8485
memmap[dynlib_path] = dynlib_baseaddr
8586
else:
8687
framePC = int(stack_tokens[2], 16) + int(stack_tokens[-1], 10)
87-
full_stack.append({"line": line, "framePC": framePC})
88+
full_stack.append(
89+
{"line": line, "framePC": framePC, "dynlib_fname": dynlib_fname})
8890

8991
lldb_target = create_lldb_target(binary, memmap)
9092
frame_idx = 0
9193
for frame in full_stack:
9294
use_orig_line = True
9395
frame_addr = frame["framePC"]
96+
dynlib_fname = frame["dynlib_fname"]
9497
so_addr = lldb_target.ResolveLoadAddress(frame_addr-1)
9598
sym_ctx = so_addr.GetSymbolContext(lldb.eSymbolContextEverything)
96-
frame_fragment = "{0: <4d} 0x{1:016x}".format(frame_idx, frame_addr)
99+
frame_fragment = "{0: <4d} {1:20s} 0x{2:016x}".format(
100+
frame_idx, dynlib_fname, frame_addr)
97101
symbol = sym_ctx.GetSymbol()
98102
if symbol.IsValid():
99103
symbol_base = symbol.GetStartAddress().GetLoadAddress(lldb_target)
@@ -127,7 +131,10 @@ def main():
127131
args = parser.parse_args()
128132

129133
binary = args.binary
130-
logfile = args.log
134+
if args.log == "-":
135+
logfile = sys.stdin
136+
else:
137+
logfile = open(args.log, 'rU')
131138

132139
lddoutput = subprocess.check_output(
133140
['ldd', binary], stderr=subprocess.STDOUT)
@@ -136,19 +143,18 @@ def main():
136143
instack = False
137144
stackidx = 0
138145
stack = []
139-
with open(logfile, 'rU') as f:
140-
for line in f:
141-
if instack and line.startswith(str(stackidx)):
142-
stack.append(line)
143-
stackidx = stackidx + 1
144-
else:
145-
instack = False
146-
stackidx = 0
147-
process_stack(binary, dyn_libs, stack)
148-
stack = []
149-
print(line.rstrip())
150-
if line.startswith("Current stack trace:"):
151-
instack = True
146+
for line in logfile:
147+
if instack and line.startswith(str(stackidx)):
148+
stack.append(line)
149+
stackidx = stackidx + 1
150+
else:
151+
instack = False
152+
stackidx = 0
153+
process_stack(binary, dyn_libs, stack)
154+
stack = []
155+
print(line.rstrip())
156+
if line.startswith("Current stack trace:"):
157+
instack = True
152158
process_stack(binary, dyn_libs, stack)
153159

154160

validation-test/lit.site.cfg.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
import sys
1414
import platform
1515

16-
## Autogenerated by Swift configuration.
17-
# Do not edit!
1816
config.llvm_src_root = "@LLVM_MAIN_SRC_DIR@"
1917
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
2018
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"

0 commit comments

Comments
 (0)