102 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//8// This file implements the functionality associated with the terminate_handler,9// unexpected_handler, and new_handler.10//===----------------------------------------------------------------------===//11 12#include <stdexcept>13#include <new>14#include <exception>15#include "abort_message.h"16#include "cxxabi.h"17#include "cxa_handlers.h"18#include "cxa_exception.h"19#include "private_typeinfo.h"20#include "include/atomic_support.h" // from libc++21 22namespace std23{24 25unexpected_handler26get_unexpected() noexcept27{28 return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);29}30 31void32__unexpected(unexpected_handler func)33{34 func();35 // unexpected handler should not return36 __abort_message("unexpected_handler unexpectedly returned");37}38 39__attribute__((noreturn))40void41unexpected()42{43 __unexpected(get_unexpected());44}45 46terminate_handler47get_terminate() noexcept48{49 return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);50}51 52void53__terminate(terminate_handler func) noexcept54{55#ifndef _LIBCXXABI_NO_EXCEPTIONS56 try57 {58#endif // _LIBCXXABI_NO_EXCEPTIONS59 func();60 // handler should not return61 __abort_message("terminate_handler unexpectedly returned");62#ifndef _LIBCXXABI_NO_EXCEPTIONS63 }64 catch (...)65 {66 // handler should not throw exception67 __abort_message("terminate_handler unexpectedly threw an exception");68 }69#endif // _LIBCXXABI_NO_EXCEPTIONS70}71 72__attribute__((noreturn))73void74terminate() noexcept75{76#ifndef _LIBCXXABI_NO_EXCEPTIONS77 // If there might be an uncaught exception78 using namespace __cxxabiv1;79 __cxa_eh_globals* globals = __cxa_get_globals_fast();80 if (globals)81 {82 __cxa_exception* exception_header = globals->caughtExceptions;83 if (exception_header)84 {85 _Unwind_Exception* unwind_exception =86 reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;87 if (__isOurExceptionClass(unwind_exception))88 __terminate(exception_header->terminateHandler);89 }90 }91#endif92 __terminate(get_terminate());93}94 95new_handler96get_new_handler() noexcept97{98 return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire);99}100 101} // std102