[Demangling] Fix duplicate _gCRAnnotations symbol problems.

Moved the _gCRAnnotations declarations to their own object module,
which will help to avoid duplicate symbol problems (at least with .a
files).

Also tweaked things to make it so that the demangler and runtime
versions of the message setting code will interoperate (and so that
they'll interoperate better with other implementations that might
creep in from somewhere, like the one in LLVMSupport).

rdar://91095592
This commit is contained in:
Alastair Houghton
2022-03-31 13:04:09 +01:00
parent 66999cecc3
commit 3f49b8be32
12 changed files with 186 additions and 115 deletions

View File

@@ -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})

View File

@@ -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

View File

@@ -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 <inttypes.h>
#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

View File

@@ -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 <android/log.h>
#endif
#if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
#include "swift/Runtime/Debug.h"
#endif
#if !SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
#if SWIFT_HAVE_CRASHREPORTERCLIENT
#include <atomic>
#include <malloc/malloc.h>
#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 <malloc/malloc.h>
#include <pthread.h>
#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<uint64_t>(message);
}
static inline const char *CRGetCrashLogMessage() {
return reinterpret_cast<const char *>(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<char *> *)&gCRAnnotations.message,
std::memory_order_relaxed);
char *oldMessage = const_cast<char *>(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<char *> *)&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

View File

@@ -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()

View File

@@ -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)

View File

@@ -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)

View File

@@ -32,6 +32,7 @@ set(swift_runtime_sources
AutoDiffSupport.cpp
Bincompat.cpp
Casting.cpp
CrashReporter.cpp
CygwinPort.cpp
Demangle.cpp
DynamicCast.cpp

View File

@@ -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

View File

@@ -57,6 +57,11 @@
#include <inttypes.h>
#ifdef SWIFT_HAVE_CRASHREPORTERCLIENT
#include <atomic>
#include <malloc/malloc.h>
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT
namespace FatalErrorFlags {
enum: uint32_t {
ReportBacktrace = 1 << 0
@@ -254,47 +259,34 @@ void swift::printCurrentBacktrace(unsigned framesToSkip) {
fprintf(stderr, "<backtrace unavailable>\n");
}
#ifdef SWIFT_HAVE_CRASHREPORTERCLIENT
#include <malloc/malloc.h>
// 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<char *> *)&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<char *> *)&gCRAnnotations.message,
&oldMessage, newMessage,
std::memory_order_release,
std::memory_order_relaxed));
#else
// empty
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT

View File

@@ -123,7 +123,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
# and the stdlib.
$<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
$<TARGET_OBJECTS:swiftLLVMSupport${SWIFT_PRIMARY_VARIANT_SUFFIX}>
$<TARGET_OBJECTS:swiftDemanglingForCore${SWIFT_PRIMARY_VARIANT_SUFFIX}>
$<TARGET_OBJECTS:swiftDemangling${SWIFT_PRIMARY_VARIANT_SUFFIX}>
)
# The local stdlib implementation provides definitions of the swiftCore

View File

@@ -44,7 +44,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
# and the stdlib.
$<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
$<TARGET_OBJECTS:swiftLLVMSupport${SWIFT_PRIMARY_VARIANT_SUFFIX}>
$<TARGET_OBJECTS:swiftDemanglingForCore${SWIFT_PRIMARY_VARIANT_SUFFIX}>
$<TARGET_OBJECTS:swiftDemangling${SWIFT_PRIMARY_VARIANT_SUFFIX}>
)
# The local stdlib implementation provides definitions of the swiftCore