diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index 76702543d25dd..414ea2517be76 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -540,6 +540,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/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index c715b7678caaf..f80eb0cd7a2c5 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -99,8 +99,10 @@ set(LLVM_OPTIONAL_SOURCES ${swift_runtime_leaks_sources} ${swift_runtime_backtracing_sources}) +set(swift_enable_backtracing) if(SWIFT_ENABLE_BACKTRACING) list(APPEND swift_runtime_sources ${swift_runtime_backtracing_sources}) + set(swift_enable_backtracing -DSWIFT_ENABLE_BACKTRACING) endif() set(swift_runtime_library_compile_flags ${swift_runtime_compile_flags}) @@ -159,7 +161,9 @@ endforeach() add_swift_target_library(swiftImageRegistrationObjectELF OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE SwiftRT-ELF.cpp - C_COMPILE_FLAGS ${SWIFT_RUNTIME_CORE_CXX_FLAGS} + C_COMPILE_FLAGS + ${SWIFT_RUNTIME_CORE_CXX_FLAGS} + ${swift_enable_backtracing} C_COMPILE_FLAGS_LINUX -fno-lto LINK_FLAGS ${SWIFT_RUNTIME_CORE_LINK_FLAGS} TARGET_SDKS ${ELFISH_SDKS} @@ -170,7 +174,9 @@ add_swift_target_library(swiftImageRegistrationObjectELF add_swift_target_library(swiftImageRegistrationObjectCOFF OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE SwiftRT-COFF.cpp - C_COMPILE_FLAGS ${SWIFT_RUNTIME_CORE_CXX_FLAGS} + C_COMPILE_FLAGS + ${SWIFT_RUNTIME_CORE_CXX_FLAGS} + ${swift_enable_backtracing} LINK_FLAGS ${SWIFT_RUNTIME_CORE_LINK_FLAGS} TARGET_SDKS ${COFF_SDKS} SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS} diff --git a/stdlib/public/runtime/SwiftRT-ELF.cpp b/stdlib/public/runtime/SwiftRT-ELF.cpp index 1b9bf3b9aa7d1..64d62f3de0927 100644 --- a/stdlib/public/runtime/SwiftRT-ELF.cpp +++ b/stdlib/public/runtime/SwiftRT-ELF.cpp @@ -12,12 +12,20 @@ #include "ImageInspectionCommon.h" #include "swift/shims/MetadataSections.h" +#include "swift/Runtime/Backtrace.h" #include #include extern "C" const char __dso_handle[]; +#if SWIFT_ENABLE_BACKTRACING +// 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; +#endif + // 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 76d61f614b7dd..087ac6b825186 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -352,6 +352,7 @@ config.rth = make_path(config.swift_utils, 'rth') # Resilience test helper config.scale_test = make_path(config.swift_utils, 'scale-test') config.PathSanitizingFileCheck = make_path(config.swift_utils, 'PathSanitizingFileCheck') config.swift_lib_dir = make_path(config.swift, '..', '..', 'lib') +config.swift_libexec_dir = make_path(config.swift, '..', '..', 'libexec') 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') @@ -555,6 +556,7 @@ else: config.substitutions.append( ('%llvm_obj_root', config.llvm_obj_root) ) config.substitutions.append( ('%swift-lib-dir', config.swift_lib_dir) ) config.substitutions.append( ('%swift-host-lib-dir', config.swift_host_lib_dir)) +config.substitutions.append( ('%swift-libexec-dir', config.swift_lib_dir) ) config.substitutions.append( ('%llvm_src_root', config.llvm_src_root) ) config.substitutions.append( ('%swift_obj_root', config.swift_obj_root) ) config.substitutions.append( ('%swift_src_root', config.swift_src_root) ) @@ -1954,6 +1956,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':