diff --git a/lib/Demangling/CMakeLists.txt b/lib/Demangling/CMakeLists.txt index 4c24da1e358..2b4fa3b60c4 100644 --- a/lib/Demangling/CMakeLists.txt +++ b/lib/Demangling/CMakeLists.txt @@ -18,7 +18,8 @@ add_swift_host_library(swiftDemangling STATIC OldRemangler.cpp Punycode.cpp Remangler.cpp - Errors.cpp) + Errors.cpp + CrashReporter.cpp) target_compile_definitions(swiftDemangling PRIVATE ${swift_demangling_compile_flags}) diff --git a/lib/Demangling/CrashReporter.cpp b/lib/Demangling/CrashReporter.cpp new file mode 100644 index 00000000000..ece5fb61c5f --- /dev/null +++ b/lib/Demangling/CrashReporter.cpp @@ -0,0 +1,35 @@ +//===--- CrashReporter.cpp - Crash Reporter integration ---------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Declares gCRAnnotations. This lets us link with other static libraries +// that also declare gCRAnnotations, because we'll pull in their copy +// (assuming they're linked first). +// +//===----------------------------------------------------------------------===// + +#include "CrashReporter.h" + +#if SWIFT_HAVE_CRASHREPORTERCLIENT + +// Instead of linking to CrashReporterClient.a (because it complicates the +// build system), define the only symbol from that static archive ourselves. +// +// The layout of this struct is CrashReporter ABI, so there are no ABI concerns +// here. +extern "C" { +SWIFT_LIBRARY_VISIBILITY +struct crashreporter_annotations_t gCRAnnotations __attribute__(( + __section__("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = { + CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0}; +} + +#endif diff --git a/lib/Demangling/CrashReporter.h b/lib/Demangling/CrashReporter.h new file mode 100644 index 00000000000..d9d838047ea --- /dev/null +++ b/lib/Demangling/CrashReporter.h @@ -0,0 +1,50 @@ +//===--- CrashReporter.h - Crash Reporter integration -----------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Declares gCRAnnotations. This lets us link with other static libraries +// that also declare gCRAnnotations, because we'll pull in their copy +// (assuming they're linked first). +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_DEMANGLING_CRASHREPORTER_H +#define SWIFT_DEMANGLING_CRASHREPORTER_H + +#if SWIFT_HAVE_CRASHREPORTERCLIENT + +// For SWIFT_LIBRARY_VISIBILITY +#include "../../stdlib/public/SwiftShims/Visibility.h" + +#include + +#define CRASHREPORTER_ANNOTATIONS_VERSION 5 +#define CRASHREPORTER_ANNOTATIONS_SECTION "__crash_info" + +struct crashreporter_annotations_t { + uint64_t version; // unsigned long + uint64_t message; // char * + uint64_t signature_string; // char * + uint64_t backtrace; // char * + uint64_t message2; // char * + uint64_t thread; // uint64_t + uint64_t dialog_mode; // unsigned int + uint64_t abort_cause; // unsigned int +}; + +extern "C" { +SWIFT_LIBRARY_VISIBILITY +extern struct crashreporter_annotations_t gCRAnnotations; +} + +#endif // SWIFT_HAVE_CRASHREPORTERCLIENT + +#endif // SWIFT_DEMANGLING_CRASHREPORTER_H diff --git a/lib/Demangling/Errors.cpp b/lib/Demangling/Errors.cpp index 647fd1ff90f..c833fbee675 100644 --- a/lib/Demangling/Errors.cpp +++ b/lib/Demangling/Errors.cpp @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// // -// This file is the public API of the demangler library. -// Tools which use the demangler library (like lldb) must include this - and -// only this - header file. +// Provides the demangling library with its own error handling functions. +// This is necessary because it isn't always linked with the runtime, so +// it can't use the runtime's error handling. // //===----------------------------------------------------------------------===// @@ -33,11 +33,11 @@ #include #endif -#if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS -#include "swift/Runtime/Debug.h" -#endif - -#if !SWIFT_DEMANGLE_USE_RUNTIME_ERRORS +#if SWIFT_HAVE_CRASHREPORTERCLIENT +#include +#include +#include "CrashReporter.h" +#endif // SWIFT_HAVE_CRASHREPORTERCLIENT // -- Declarations ----------------------------------------------------------- @@ -54,75 +54,41 @@ static int demangle_asprintf(char **strp, const char *format, ...); // -- Crash reporter integration --------------------------------------------- #if SWIFT_HAVE_CRASHREPORTERCLIENT -#include -#include - -#define CRASHREPORTER_ANNOTATIONS_VERSION 5 -#define CRASHREPORTER_ANNOTATIONS_SECTION "__crash_info" - -struct crashreporter_annotations_t { - uint64_t version; // unsigned long - uint64_t message; // char * - uint64_t signature_string; // char * - uint64_t backtrace; // char * - uint64_t message2; // char * - uint64_t thread; // uint64_t - uint64_t dialog_mode; // unsigned int - uint64_t abort_cause; // unsigned int -}; - -// Instead of linking to CrashReporterClient.a (because it complicates the -// build system), define the only symbol from that static archive ourselves. -// -// The layout of this struct is CrashReporter ABI, so there are no ABI concerns -// here. -extern "C" { -SWIFT_LIBRARY_VISIBILITY -struct crashreporter_annotations_t gCRAnnotations __attribute__(( - __section__("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = { - CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0}; -} - -static inline void CRSetCrashLogMessage(const char *message) { - gCRAnnotations.message = reinterpret_cast(message); -} - -static inline const char *CRGetCrashLogMessage() { - return reinterpret_cast(gCRAnnotations.message); -} - // Report a message to any forthcoming crash log. static void reportOnCrash(uint32_t flags, const char *message) { - // We must use an "unsafe" mutex in this pathway since the normal "safe" - // mutex calls fatal when an error is detected and fatal ends up - // calling us. In other words we could get infinite recursion if the - // mutex errors. - static pthread_mutex_t crashlogLock = PTHREAD_MUTEX_INITIALIZER; + char *oldMessage = nullptr; + char *newMessage = nullptr; - pthread_mutex_lock(&crashlogLock); + oldMessage = std::atomic_load_explicit( + (volatile std::atomic *)&gCRAnnotations.message, + std::memory_order_relaxed); - char *oldMessage = const_cast(CRGetCrashLogMessage()); - char *newMessage; - if (oldMessage) { - demangle_asprintf(&newMessage, "%s%s", oldMessage, message); - if (malloc_size(oldMessage)) - free(oldMessage); - } else { - newMessage = strdup(message); - } + do { + if (newMessage) { + free(newMessage); + newMessage = nullptr; + } - CRSetCrashLogMessage(newMessage); + if (oldMessage) { + demangle_asprintf(&newMessage, "%s%s", oldMessage, message); + } else { + newMessage = strdup(message); + } + } while (!std::atomic_compare_exchange_strong_explicit( + (volatile std::atomic *)&gCRAnnotations.message, + &oldMessage, newMessage, + std::memory_order_release, + std::memory_order_relaxed)); - pthread_mutex_unlock(&crashlogLock); + if (oldMessage && malloc_size(oldMessage)) + free(oldMessage); } #else static void - reportOnCrash(uint32_t flags, const char *message) { // empty } - #endif // SWIFT_HAVE_CRASHREPORTERCLIENT // -- Utility functions ------------------------------------------------------ @@ -219,8 +185,6 @@ static void demangleWarn(uint32_t flags, const char *format, va_list val) { free(message); } -#endif // !SWIFT_DEMANGLE_USE_RUNTIME_ERRORS - // -- Public API ------------------------------------------------------------- namespace swift { @@ -243,19 +207,11 @@ void warn(uint32_t flags, const char *format, ...) { } SWIFT_NORETURN void fatalv(uint32_t flags, const char *format, va_list val) { -#if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS - swift::fatalErrorv(flags, format, val); -#else demangleFatal(flags, format, val); -#endif } void warnv(uint32_t flags, const char *format, va_list val) { -#if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS - swift::warningv(flags, format, val); -#else demangleWarn(flags, format, val); -#endif } SWIFT_END_INLINE_NAMESPACE diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt index 21aef86b9cc..ddeab44acd9 100644 --- a/stdlib/public/CMakeLists.txt +++ b/stdlib/public/CMakeLists.txt @@ -79,6 +79,8 @@ if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR) "${SWIFT_SOURCE_DIR}/lib/Demangling/Remangler.cpp" "${SWIFT_SOURCE_DIR}/lib/Demangling/NodeDumper.cpp" "${SWIFT_SOURCE_DIR}/lib/Demangling/Errors.cpp") + set(swiftDemanglingCRSources + "${SWIFT_SOURCE_DIR}/lib/Demangling/CrashReporter.cpp") set(swift_demangling_cflags) @@ -109,11 +111,10 @@ if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR) ${swift_demangling_cflags} INSTALL_IN_COMPONENT never_install) - add_swift_target_library(swiftDemanglingForCore OBJECT_LIBRARY - ${swiftDemanglingSources} + add_swift_target_library(swiftDemanglingCR OBJECT_LIBRARY + ${swiftDemanglingCRSources} C_COMPILE_FLAGS -DswiftCore_EXPORTS - -DSWIFT_DEMANGLE_USE_RUNTIME_ERRORS=1 ${swift_demangling_cflags} INSTALL_IN_COMPONENT never_install) endif() diff --git a/stdlib/public/Reflection/CMakeLists.txt b/stdlib/public/Reflection/CMakeLists.txt index 0a56ee79646..c0dd1a21b5e 100644 --- a/stdlib/public/Reflection/CMakeLists.txt +++ b/stdlib/public/Reflection/CMakeLists.txt @@ -14,6 +14,6 @@ add_swift_target_library(swiftReflection STATIC C_COMPILE_FLAGS ${SWIFT_RUNTIME_CXX_FLAGS} ${swiftReflection_C_COMPILE_FLAGS} LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS} INCORPORATE_OBJECT_LIBRARIES - swiftLLVMSupport swiftDemangling + swiftLLVMSupport swiftDemangling swiftDemanglingCR SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS} INSTALL_IN_COMPONENT dev) diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index b3e69d1bcae..8cad9b1013e 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -295,7 +295,7 @@ endif() set(swift_core_incorporate_object_libraries) list(APPEND swift_core_incorporate_object_libraries swiftRuntime) list(APPEND swift_core_incorporate_object_libraries swiftLLVMSupport) -list(APPEND swift_core_incorporate_object_libraries swiftDemanglingForCore) +list(APPEND swift_core_incorporate_object_libraries swiftDemangling) list(APPEND swift_core_incorporate_object_libraries swiftStdlibStubs) if(SWIFT_STDLIB_HAS_COMMANDLINE) list(APPEND swift_core_incorporate_object_libraries swiftCommandLineSupport) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 5a5216f3135..d4193f37faa 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -32,6 +32,7 @@ set(swift_runtime_sources AutoDiffSupport.cpp Bincompat.cpp Casting.cpp + CrashReporter.cpp CygwinPort.cpp Demangle.cpp DynamicCast.cpp diff --git a/stdlib/public/runtime/CrashReporter.cpp b/stdlib/public/runtime/CrashReporter.cpp new file mode 100644 index 00000000000..fd7e891579d --- /dev/null +++ b/stdlib/public/runtime/CrashReporter.cpp @@ -0,0 +1,35 @@ +//===--- CrashReporter.cpp - Crash Reporter integration ---------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Declares gCRAnnotations. This lets us link with other static libraries +// that also declare gCRAnnotations, because we'll pull in their copy +// (assuming they're linked first). +// +//===----------------------------------------------------------------------===// + +#include "swift/Runtime/Debug.h" + +#if SWIFT_HAVE_CRASHREPORTERCLIENT + +// Instead of linking to CrashReporterClient.a (because it complicates the +// build system), define the only symbol from that static archive ourselves. +// +// The layout of this struct is CrashReporter ABI, so there are no ABI concerns +// here. +extern "C" { +SWIFT_LIBRARY_VISIBILITY +struct crashreporter_annotations_t gCRAnnotations __attribute__(( + __section__("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = { + CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0}; +} + +#endif diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp index ffe48be97c7..34120dce52f 100644 --- a/stdlib/public/runtime/Errors.cpp +++ b/stdlib/public/runtime/Errors.cpp @@ -57,6 +57,11 @@ #include +#ifdef SWIFT_HAVE_CRASHREPORTERCLIENT +#include +#include +#endif // SWIFT_HAVE_CRASHREPORTERCLIENT + namespace FatalErrorFlags { enum: uint32_t { ReportBacktrace = 1 << 0 @@ -254,47 +259,34 @@ void swift::printCurrentBacktrace(unsigned framesToSkip) { fprintf(stderr, "\n"); } -#ifdef SWIFT_HAVE_CRASHREPORTERCLIENT -#include - -// Instead of linking to CrashReporterClient.a (because it complicates the -// build system), define the only symbol from that static archive ourselves. -// -// The layout of this struct is CrashReporter ABI, so there are no ABI concerns -// here. -extern "C" { -SWIFT_LIBRARY_VISIBILITY -struct crashreporter_annotations_t gCRAnnotations -__attribute__((__section__("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = { - CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0}; -} -#endif // SWIFT_HAVE_CRASHREPORTERCLIENT - // Report a message to any forthcoming crash log. static void reportOnCrash(uint32_t flags, const char *message) { #ifdef SWIFT_HAVE_CRASHREPORTERCLIENT - // We must use an "unsafe" mutex in this pathway since the normal "safe" - // mutex calls fatalError when an error is detected and fatalError ends up - // calling us. In other words we could get infinite recursion if the - // mutex errors. - static swift::StaticUnsafeMutex crashlogLock; + char *oldMessage = nullptr; + char *newMessage = nullptr; - crashlogLock.lock(); + oldMessage = std::atomic_load_explicit( + (volatile std::atomic *)&gCRAnnotations.message, + std::memory_order_relaxed); - char *oldMessage = (char *)CRGetCrashLogMessage(); - char *newMessage; - if (oldMessage) { - swift_asprintf(&newMessage, "%s%s", oldMessage, message); - if (malloc_size(oldMessage)) free(oldMessage); - } else { - newMessage = strdup(message); - } - - CRSetCrashLogMessage(newMessage); + do { + if (newMessage) { + free(newMessage); + newMessage = nullptr; + } - crashlogLock.unlock(); + if (oldMessage) { + swift_asprintf(&newMessage, "%s%s", oldMessage, message); + } else { + newMessage = strdup(message); + } + } while (!std::atomic_compare_exchange_strong_explicit( + (volatile std::atomic *)&gCRAnnotations.message, + &oldMessage, newMessage, + std::memory_order_release, + std::memory_order_relaxed)); #else // empty #endif // SWIFT_HAVE_CRASHREPORTERCLIENT diff --git a/unittests/runtime/CMakeLists.txt b/unittests/runtime/CMakeLists.txt index 038d082b680..7cc74e728e5 100644 --- a/unittests/runtime/CMakeLists.txt +++ b/unittests/runtime/CMakeLists.txt @@ -123,7 +123,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND # and the stdlib. $ $ - $ + $ ) # The local stdlib implementation provides definitions of the swiftCore diff --git a/unittests/runtime/LongTests/CMakeLists.txt b/unittests/runtime/LongTests/CMakeLists.txt index 1df6153c18b..0ae5d597bf6 100644 --- a/unittests/runtime/LongTests/CMakeLists.txt +++ b/unittests/runtime/LongTests/CMakeLists.txt @@ -44,7 +44,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND # and the stdlib. $ $ - $ + $ ) # The local stdlib implementation provides definitions of the swiftCore