diff options
Diffstat (limited to 'system/lib/libcxxabi/src/cxa_handlers.cpp')
-rw-r--r-- | system/lib/libcxxabi/src/cxa_handlers.cpp | 109 |
1 files changed, 19 insertions, 90 deletions
diff --git a/system/lib/libcxxabi/src/cxa_handlers.cpp b/system/lib/libcxxabi/src/cxa_handlers.cpp index be43181c..6c13fcd2 100644 --- a/system/lib/libcxxabi/src/cxa_handlers.cpp +++ b/system/lib/libcxxabi/src/cxa_handlers.cpp @@ -22,85 +22,13 @@ namespace std { -static const char* cause = "uncaught"; - -static void default_terminate_handler() -{ - // If there might be an uncaught exception - using namespace __cxxabiv1; - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - if (globals) - { - __cxa_exception* exception_header = globals->caughtExceptions; - // If there is an uncaught exception - if (exception_header) - { - _Unwind_Exception* unwind_exception = - reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; - bool native_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - if (native_exception) - { - void* thrown_object = - unwind_exception->exception_class == kOurDependentExceptionClass ? - ((__cxa_dependent_exception*)exception_header)->primaryException : - exception_header + 1; - const __shim_type_info* thrown_type = - static_cast<const __shim_type_info*>(exception_header->exceptionType); - // Try to get demangled name of thrown_type - int status; - char buf[1024]; - size_t len = sizeof(buf); - const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status); - if (status != 0) - name = thrown_type->name(); - // If the uncaught exception can be caught with std::exception& - const __shim_type_info* catch_type = - static_cast<const __shim_type_info*>(&typeid(exception)); - if (catch_type->can_catch(thrown_type, thrown_object)) - { - // Include the what() message from the exception - const exception* e = static_cast<const exception*>(thrown_object); - abort_message("terminating with %s exception of type %s: %s", - cause, name, e->what()); - } - else - // Else just note that we're terminating with an exception - abort_message("terminating with %s exception of type %s", - cause, name); - } - else - // Else we're terminating with a foreign exception - abort_message("terminating with %s foreign exception", cause); - } - } - // Else just note that we're terminating - abort_message("terminating"); -} - -static void default_unexpected_handler() -{ - cause = "unexpected"; - terminate(); -} - -static terminate_handler __terminate_handler = default_terminate_handler; -static unexpected_handler __unexpected_handler = default_unexpected_handler; -static new_handler __new_handler = 0; - -unexpected_handler -set_unexpected(unexpected_handler func) _NOEXCEPT -{ - if (func == 0) - func = default_unexpected_handler; - return __sync_lock_test_and_set(&__unexpected_handler, func); -} - unexpected_handler get_unexpected() _NOEXCEPT { - return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0); + return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0); +// The above is safe but overkill on x86 +// Using of C++11 atomics this should be rewritten +// return __cxa_unexpected_handler.load(memory_order_acq); } __attribute__((visibility("hidden"), noreturn)) @@ -120,17 +48,12 @@ unexpected() } terminate_handler -set_terminate(terminate_handler func) _NOEXCEPT -{ - if (func == 0) - func = default_terminate_handler; - return __sync_lock_test_and_set(&__terminate_handler, func); -} - -terminate_handler get_terminate() _NOEXCEPT { - return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0); + return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0); +// The above is safe but overkill on x86 +// Using of C++11 atomics this should be rewritten +// return __cxa_terminate_handler.load(memory_order_acq); } __attribute__((visibility("hidden"), noreturn)) @@ -172,25 +95,31 @@ terminate() _NOEXCEPT (unwind_exception->exception_class & get_vendor_and_language) == (kOurExceptionClass & get_vendor_and_language); if (native_exception) - { - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; __terminate(exception_header->terminateHandler); - } } } __terminate(get_terminate()); } +extern "C" new_handler __cxa_new_handler = 0; +// In the future these will become: +// std::atomic<std::new_handler> __cxa_new_handler(0); + new_handler set_new_handler(new_handler handler) _NOEXCEPT { - return __sync_lock_test_and_set(&__new_handler, handler); + return __sync_swap(&__cxa_new_handler, handler); +// Using of C++11 atomics this should be rewritten +// return __cxa_new_handler.exchange(handler, memory_order_acq_rel); } new_handler get_new_handler() _NOEXCEPT { - return __sync_fetch_and_add(&__new_handler, (new_handler)0); + return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0); +// The above is safe but overkill on x86 +// Using of C++11 atomics this should be rewritten +// return __cxa_new_handler.load(memory_order_acq); } } // std |