diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index b55f7d8071656..44b84c7e1333a 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -543,6 +543,7 @@ function(_add_swift_runtime_link_flags target relpath_to_lib_dir bootstrapping) get_filename_component(swift_bin_dir ${SWIFT_EXEC_FOR_SWIFT_MODULES} DIRECTORY) get_filename_component(swift_dir ${swift_bin_dir} DIRECTORY) set(host_lib_dir "${swift_dir}/lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}") + set(swiftrt "${host_lib_dir}/${SWIFT_HOST_VARIANT_ARCH}/swiftrt.o") target_link_libraries(${target} PRIVATE ${swiftrt}) target_link_libraries(${target} PRIVATE "swiftCore") diff --git a/stdlib/public/runtime/SwiftRT-ELF-WASM.cpp b/stdlib/public/runtime/SwiftRT-ELF-WASM.cpp index e68103a6a6750..ff3ac5b192a4a 100644 --- a/stdlib/public/runtime/SwiftRT-ELF-WASM.cpp +++ b/stdlib/public/runtime/SwiftRT-ELF-WASM.cpp @@ -12,6 +12,7 @@ #include "ImageInspectionCommon.h" #include "swift/shims/MetadataSections.h" +#include "swift/Runtime/Backtrace.h" #include #include @@ -24,6 +25,11 @@ extern "C" const char __dso_handle[]; static constexpr const void *__dso_handle = nullptr; #endif +// Drag in a symbol from the backtracer, to force the static linker to include +// the code. +static const void *__backtraceRef __attribute__((used)) + = (const void *)swift::runtime::backtrace::_swift_backtrace_isThunkFunction; + // Create empty sections to ensure that the start/stop symbols are synthesized // by the linker. Otherwise, we may end up with undefined symbol references as // the linker table section was never constructed. diff --git a/test/Backtracing/CrashStatic.swift b/test/Backtracing/CrashStatic.swift new file mode 100644 index 0000000000000..6ada723f484f5 --- /dev/null +++ b/test/Backtracing/CrashStatic.swift @@ -0,0 +1,60 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift %s -parse-as-library %import-static-libdispatch -Onone -static-stdlib -g -o %t/CrashStatic +// RUN: %target-codesign %t/CrashStatic +// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no,swift-backtrace=%backtracer %target-run %t/CrashStatic 2>&1 || true) | %FileCheck %s + +// UNSUPPORTED: use_os_stdlib +// UNSUPPORTED: back_deployment_runtime +// UNSUPPORTED: asan +// REQUIRES: executable_test +// REQUIRES: backtracing +// REQUIRES: static_stdlib +// REQUIRES: OS=linux-gnu + +func level1() { + level2() +} + +func level2() { + level3() +} + +func level3() { + level4() +} + +func level4() { + level5() +} + +func level5() { + print("About to crash") + let ptr = UnsafeMutablePointer(bitPattern: 4)! + ptr.pointee = 42 +} + +@main +struct CrashStatic { + static func main() { + level1() + } +} + +// CHECK: *** Program crashed: Bad pointer dereference at 0x{{0+}}4 *** + +// CHECK: Thread 0 {{(".*" )?}}crashed: + +// CHECK: 0 0x{{[0-9a-f]+}} level5() + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift:33:15 +// CHECK-NEXT: 1 [ra] 0x{{[0-9a-f]+}} level4() + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift:27:3 +// CHECK-NEXT: 2 [ra] 0x{{[0-9a-f]+}} level3() + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift:23:3 +// CHECK-NEXT: 3 [ra] 0x{{[0-9a-f]+}} level2() + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift:19:3 +// CHECK-NEXT: 4 [ra] 0x{{[0-9a-f]+}} level1() + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift:15:3 +// CHECK-NEXT: 5 [ra] 0x{{[0-9a-f]+}} static CrashStatic.main() + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift:39:5 +// CHECK-NEXT: 6 [ra] [system] 0x{{[0-9a-f]+}} static CrashStatic.$main() + {{[0-9]+}} in CrashStatic at {{.*}}/ +// CHECK-NEXT: 7 [ra] 0x{{[0-9a-f]+}} main + {{[0-9]+}} in CrashStatic at {{.*}}/CrashStatic.swift + +// CHECK: Registers: + +// CHECK: Images ({{[0-9]+}} omitted): + +// CHECK: {{0x[0-9a-f]+}}–{{0x[0-9a-f]+}}{{ +}}{{([0-9a-f]+|)}}{{ +}}CrashStatic{{ +}}{{.*}}/CrashStatic diff --git a/test/lit.cfg b/test/lit.cfg index 62b1c25671b72..11e34c0788a22 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -354,6 +354,7 @@ config.scale_test = make_path(config.swift_utils, 'scale-test') config.PathSanitizingFileCheck = make_path(config.swift_utils, 'PathSanitizingFileCheck') config.swift_bin_dir = make_path(config.swift, '..', '..', 'bin') config.swift_lib_dir = make_path(config.swift, '..', '..', 'lib') +config.swift_libexec_dir = make_path(config.swift, '..', '..', 'libexec') config.swift_share_dir = make_path(config.swift, '..', '..', 'share') config.round_trip_syntax_test = make_path(config.swift_utils, 'round-trip-syntax-test') config.refactor_check_compiles = make_path(config.swift_utils, 'refactor-check-compiles.py') @@ -588,6 +589,7 @@ else: config.substitutions.append( ('%llvm_obj_root', config.llvm_obj_root) ) config.substitutions.append( ('%swift-bin-dir', config.swift_bin_dir) ) config.substitutions.append( ('%swift-lib-dir', config.swift_lib_dir) ) +config.substitutions.append( ('%swift-libexec-dir', config.swift_lib_dir) ) config.substitutions.append( ('%swift-share-dir', config.swift_share_dir) ) config.substitutions.append( ('%swift-plugin-dir', config.swift_plugin_dir) ) config.substitutions.append( ('%llvm_src_root', config.llvm_src_root) ) @@ -1998,6 +2000,10 @@ if run_vendor == 'apple': config.available_features.add('back_deploy_concurrency') concurrency_back_deploy_path = os.path.join(os.path.dirname(swift_obj_root), os.path.basename(swift_obj_root).replace("swift-", "backdeployconcurrency-"), 'lib', 'swift-5.5', xcrun_sdk_name) +backtracer_path = make_path(config.swift_libexec_dir, 'swift', + config.target_sdk_name, 'swift-backtrace') +config.substitutions.append(('%backtracer', backtracer_path)) + def os_stdlib_paths(): if run_vendor == 'apple': if run_os == 'maccatalyst':