1010//
1111// ===----------------------------------------------------------------------===//
1212//
13- // This file is the public API of the demangler library .
14- // Tools which use the demangler library (like lldb) must include this - and
15- // only this - header file .
13+ // Provides the demangling library with its own error handling functions .
14+ // This is necessary because it isn't always linked with the runtime, so
15+ // it can't use the runtime's error handling .
1616//
1717// ===----------------------------------------------------------------------===//
1818
3333#include < android/log.h>
3434#endif
3535
36- #if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
37- #include " swift/Runtime/Debug.h"
38- #endif
36+ #if SWIFT_HAVE_CRASHREPORTERCLIENT
37+ #include < atomic>
38+ #include < malloc/malloc.h>
39+
40+ #include " swift/Runtime/Atomic.h"
3941
40- #if !SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
42+ #include " CrashReporter.h"
43+ #endif // SWIFT_HAVE_CRASHREPORTERCLIENT
4144
4245// -- Declarations -----------------------------------------------------------
4346
@@ -53,77 +56,39 @@ static int demangle_asprintf(char **strp, const char *format, ...);
5356
5457// -- Crash reporter integration ---------------------------------------------
5558
56- #if SWIFT_HAVE_CRASHREPORTERCLIENT
57- #include < malloc/malloc.h>
58- #include < pthread.h>
59-
60- #define CRASHREPORTER_ANNOTATIONS_VERSION 5
61- #define CRASHREPORTER_ANNOTATIONS_SECTION " __crash_info"
62-
63- struct crashreporter_annotations_t {
64- uint64_t version; // unsigned long
65- uint64_t message; // char *
66- uint64_t signature_string; // char *
67- uint64_t backtrace; // char *
68- uint64_t message2; // char *
69- uint64_t thread; // uint64_t
70- uint64_t dialog_mode; // unsigned int
71- uint64_t abort_cause; // unsigned int
72- };
73-
74- // Instead of linking to CrashReporterClient.a (because it complicates the
75- // build system), define the only symbol from that static archive ourselves.
76- //
77- // The layout of this struct is CrashReporter ABI, so there are no ABI concerns
78- // here.
79- extern " C" {
80- SWIFT_LIBRARY_VISIBILITY
81- struct crashreporter_annotations_t gCRAnnotations __attribute__ ((
82- __section__ (" __DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = {
83- CRASHREPORTER_ANNOTATIONS_VERSION, 0 , 0 , 0 , 0 , 0 , 0 , 0 };
84- }
85-
86- static inline void CRSetCrashLogMessage (const char *message) {
87- gCRAnnotations .message = reinterpret_cast <uint64_t >(message);
88- }
89-
90- static inline const char *CRGetCrashLogMessage () {
91- return reinterpret_cast <const char *>(gCRAnnotations .message );
92- }
93-
9459// Report a message to any forthcoming crash log.
9560static void reportOnCrash (uint32_t flags, const char *message) {
96- // We must use an "unsafe" mutex in this pathway since the normal "safe"
97- // mutex calls fatal when an error is detected and fatal ends up
98- // calling us. In other words we could get infinite recursion if the
99- // mutex errors.
100- static pthread_mutex_t crashlogLock = PTHREAD_MUTEX_INITIALIZER;
101-
102- pthread_mutex_lock (&crashlogLock);
103-
104- char *oldMessage = const_cast <char *>(CRGetCrashLogMessage ());
105- char *newMessage;
106- if (oldMessage) {
107- demangle_asprintf (&newMessage, " %s%s" , oldMessage, message);
108- if (malloc_size (oldMessage))
109- free (oldMessage);
110- } else {
111- newMessage = strdup (message);
112- }
113-
114- CRSetCrashLogMessage (newMessage);
115-
116- pthread_mutex_unlock (&crashlogLock);
117- }
118-
61+ #if SWIFT_HAVE_CRASHREPORTERCLIENT
62+ char *oldMessage = nullptr ;
63+ char *newMessage = nullptr ;
64+
65+ oldMessage = std::atomic_load_explicit (
66+ (volatile std::atomic<char *> *)&gCRAnnotations .message ,
67+ SWIFT_MEMORY_ORDER_CONSUME);
68+
69+ do {
70+ if (newMessage) {
71+ free (newMessage);
72+ newMessage = nullptr ;
73+ }
74+
75+ if (oldMessage) {
76+ demangle_asprintf (&newMessage, " %s%s" , oldMessage, message);
77+ } else {
78+ newMessage = strdup (message);
79+ }
80+ } while (!std::atomic_compare_exchange_strong_explicit (
81+ (volatile std::atomic<char *> *)&gCRAnnotations .message ,
82+ &oldMessage, newMessage,
83+ std::memory_order_release,
84+ SWIFT_MEMORY_ORDER_CONSUME));
85+
86+ if (oldMessage && malloc_size (oldMessage))
87+ free (oldMessage);
11988#else
120- static void
121-
122- reportOnCrash (uint32_t flags, const char *message) {
12389 // empty
124- }
125-
12690#endif // SWIFT_HAVE_CRASHREPORTERCLIENT
91+ }
12792
12893// -- Utility functions ------------------------------------------------------
12994
@@ -219,8 +184,6 @@ static void demangleWarn(uint32_t flags, const char *format, va_list val) {
219184 free (message);
220185}
221186
222- #endif // !SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
223-
224187// -- Public API -------------------------------------------------------------
225188
226189namespace swift {
@@ -243,19 +206,11 @@ void warn(uint32_t flags, const char *format, ...) {
243206}
244207
245208SWIFT_NORETURN void fatalv (uint32_t flags, const char *format, va_list val) {
246- #if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
247- swift::fatalErrorv (flags, format, val);
248- #else
249209 demangleFatal (flags, format, val);
250- #endif
251210}
252211
253212void warnv (uint32_t flags, const char *format, va_list val) {
254- #if SWIFT_DEMANGLE_USE_RUNTIME_ERRORS
255- swift::warningv (flags, format, val);
256- #else
257213 demangleWarn (flags, format, val);
258- #endif
259214}
260215
261216SWIFT_END_INLINE_NAMESPACE
0 commit comments