1*8f1d5724Srobert //===----------------------------------------------------------------------===// 279c2e3e6Spatrick // 379c2e3e6Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 479c2e3e6Spatrick // See https://llvm.org/LICENSE.txt for license information. 579c2e3e6Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 679c2e3e6Spatrick // 779c2e3e6Spatrick // 879c2e3e6Spatrick // This file implements the functionality associated with the terminate_handler, 979c2e3e6Spatrick // unexpected_handler, and new_handler. 1079c2e3e6Spatrick //===----------------------------------------------------------------------===// 1179c2e3e6Spatrick 1279c2e3e6Spatrick #include <stdexcept> 1379c2e3e6Spatrick #include <new> 1479c2e3e6Spatrick #include <exception> 1579c2e3e6Spatrick #include "abort_message.h" 1679c2e3e6Spatrick #include "cxxabi.h" 1779c2e3e6Spatrick #include "cxa_handlers.h" 1879c2e3e6Spatrick #include "cxa_exception.h" 1979c2e3e6Spatrick #include "private_typeinfo.h" 20*8f1d5724Srobert #include "include/atomic_support.h" // from libc++ 2179c2e3e6Spatrick 2279c2e3e6Spatrick namespace std 2379c2e3e6Spatrick { 2479c2e3e6Spatrick 2579c2e3e6Spatrick unexpected_handler get_unexpected()264e0cc08cSpatrickget_unexpected() noexcept 2779c2e3e6Spatrick { 2879c2e3e6Spatrick return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire); 2979c2e3e6Spatrick } 3079c2e3e6Spatrick 3179c2e3e6Spatrick void __unexpected(unexpected_handler func)3279c2e3e6Spatrick__unexpected(unexpected_handler func) 3379c2e3e6Spatrick { 3479c2e3e6Spatrick func(); 3579c2e3e6Spatrick // unexpected handler should not return 3679c2e3e6Spatrick abort_message("unexpected_handler unexpectedly returned"); 3779c2e3e6Spatrick } 3879c2e3e6Spatrick 3979c2e3e6Spatrick __attribute__((noreturn)) 4079c2e3e6Spatrick void unexpected()4179c2e3e6Spatrickunexpected() 4279c2e3e6Spatrick { 4379c2e3e6Spatrick __unexpected(get_unexpected()); 4479c2e3e6Spatrick } 4579c2e3e6Spatrick 4679c2e3e6Spatrick terminate_handler get_terminate()474e0cc08cSpatrickget_terminate() noexcept 4879c2e3e6Spatrick { 4979c2e3e6Spatrick return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire); 5079c2e3e6Spatrick } 5179c2e3e6Spatrick 5279c2e3e6Spatrick void __terminate(terminate_handler func)534e0cc08cSpatrick__terminate(terminate_handler func) noexcept 5479c2e3e6Spatrick { 5579c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS 5679c2e3e6Spatrick try 5779c2e3e6Spatrick { 5879c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS 5979c2e3e6Spatrick func(); 6079c2e3e6Spatrick // handler should not return 6179c2e3e6Spatrick abort_message("terminate_handler unexpectedly returned"); 6279c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS 6379c2e3e6Spatrick } 6479c2e3e6Spatrick catch (...) 6579c2e3e6Spatrick { 6679c2e3e6Spatrick // handler should not throw exception 6779c2e3e6Spatrick abort_message("terminate_handler unexpectedly threw an exception"); 6879c2e3e6Spatrick } 6979c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS 7079c2e3e6Spatrick } 7179c2e3e6Spatrick 7279c2e3e6Spatrick __attribute__((noreturn)) 7379c2e3e6Spatrick void terminate()744e0cc08cSpatrickterminate() noexcept 7579c2e3e6Spatrick { 7679c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS 7779c2e3e6Spatrick // If there might be an uncaught exception 7879c2e3e6Spatrick using namespace __cxxabiv1; 7979c2e3e6Spatrick __cxa_eh_globals* globals = __cxa_get_globals_fast(); 8079c2e3e6Spatrick if (globals) 8179c2e3e6Spatrick { 8279c2e3e6Spatrick __cxa_exception* exception_header = globals->caughtExceptions; 8379c2e3e6Spatrick if (exception_header) 8479c2e3e6Spatrick { 8579c2e3e6Spatrick _Unwind_Exception* unwind_exception = 8679c2e3e6Spatrick reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; 8779c2e3e6Spatrick if (__isOurExceptionClass(unwind_exception)) 8879c2e3e6Spatrick __terminate(exception_header->terminateHandler); 8979c2e3e6Spatrick } 9079c2e3e6Spatrick } 9179c2e3e6Spatrick #endif 9279c2e3e6Spatrick __terminate(get_terminate()); 9379c2e3e6Spatrick } 9479c2e3e6Spatrick 9579c2e3e6Spatrick new_handler get_new_handler()964e0cc08cSpatrickget_new_handler() noexcept 9779c2e3e6Spatrick { 9879c2e3e6Spatrick return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire); 9979c2e3e6Spatrick } 10079c2e3e6Spatrick 10179c2e3e6Spatrick } // std 102