Skip to content

Runtime: add a non-Darwin error message storage #72785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/swift/Runtime/Debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ void swift_reportError(uint32_t flags, const char *message);
SWIFT_RUNTIME_EXPORT
void swift_reportWarning(uint32_t flags, const char *message);

#if !defined(SWIFT_HAVE_CRASHREPORTERCLIENT)
SWIFT_RUNTIME_EXPORT
std::atomic<const char *> *swift_getFatalErrorMessageBuffer();
#endif

// Halt due to an overflow in swift_retain().
SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
void swift_abortRetainOverflow();
Expand Down
32 changes: 28 additions & 4 deletions stdlib/public/runtime/Errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "ImageInspection.h"
#include "swift/Demangling/Demangle.h"
#include "swift/Runtime/Atomic.h"
#include "swift/Runtime/Debug.h"
#include "swift/Runtime/Portability.h"
#include "swift/Runtime/Win32.h"
Expand Down Expand Up @@ -64,14 +65,15 @@
#include <inttypes.h>

#ifdef SWIFT_HAVE_CRASHREPORTERCLIENT
#include <atomic>
#include <malloc/malloc.h>

#include "swift/Runtime/Atomic.h"
#else
static std::atomic<const char *> kFatalErrorMessage;
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT

#include "BacktracePrivate.h"

#include <atomic>

namespace FatalErrorFlags {
enum: uint32_t {
ReportBacktrace = 1 << 0
Expand Down Expand Up @@ -297,7 +299,23 @@ reportOnCrash(uint32_t flags, const char *message)
std::memory_order_release,
SWIFT_MEMORY_ORDER_CONSUME));
#else
// empty
const char *previous = nullptr;
char *current = nullptr;
previous =
std::atomic_load_explicit(&kFatalErrorMessage, SWIFT_MEMORY_ORDER_CONSUME);

do {
::free(current);
current = nullptr;

if (previous)
swift_asprintf(&current, "%s%s", current, message);
else
current = ::strdup(message);
} while (!std::atomic_compare_exchange_strong_explicit(&kFatalErrorMessage,
&previous, current,
std::memory_order_release,
SWIFT_MEMORY_ORDER_CONSUME));
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT
}

Expand Down Expand Up @@ -421,6 +439,12 @@ void swift::swift_reportWarning(uint32_t flags, const char *message) {
warning(flags, "%s", message);
}

#if !defined(SWIFT_HAVE_CRASHREPORTERCLIENT)
std::atomic<const char *> *swift::swift_getFatalErrorMessageBuffer() {
return &kFatalErrorMessage;
}
#endif

// Crash when a deleted method is called by accident.
SWIFT_RUNTIME_EXPORT SWIFT_NORETURN void swift_deletedMethodError() {
swift::fatalError(/* flags = */ 0,
Expand Down