blob: 390bc6564cbdbc28ac9ae10520151b11315f55ce [file] [log] [blame]
Howard Hinnant2642af92011-12-06 17:51:25 +00001//===------------------------- cxa_handlers.cpp ---------------------------===//
2//
Chandler Carruth57b08b02019-01-19 10:56:40 +00003// 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-exception
Howard Hinnant2642af92011-12-06 17:51:25 +00006//
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"
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000016#include "cxxabi.h"
Howard Hinnant5ec91832011-12-07 21:16:40 +000017#include "cxa_handlers.hpp"
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000018#include "cxa_exception.hpp"
19#include "private_typeinfo.h"
Eli Friedman17a47b92018-04-16 22:00:14 +000020#include "include/atomic_support.h"
Howard Hinnant2642af92011-12-06 17:51:25 +000021
22namespace std
23{
24
Howard Hinnant2642af92011-12-06 17:51:25 +000025unexpected_handler
26get_unexpected() _NOEXCEPT
27{
Eli Friedman17a47b92018-04-16 22:00:14 +000028 return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);
Howard Hinnant2642af92011-12-06 17:51:25 +000029}
30
Howard Hinnant2642af92011-12-06 17:51:25 +000031void
32__unexpected(unexpected_handler func)
33{
34 func();
35 // unexpected handler should not return
36 abort_message("unexpected_handler unexpectedly returned");
37}
38
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000039__attribute__((noreturn))
Howard Hinnant2642af92011-12-06 17:51:25 +000040void
41unexpected()
42{
43 __unexpected(get_unexpected());
44}
45
46terminate_handler
Howard Hinnant2642af92011-12-06 17:51:25 +000047get_terminate() _NOEXCEPT
48{
Eli Friedman17a47b92018-04-16 22:00:14 +000049 return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);
Howard Hinnant2642af92011-12-06 17:51:25 +000050}
51
Howard Hinnant2642af92011-12-06 17:51:25 +000052void
53__terminate(terminate_handler func) _NOEXCEPT
54{
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000055#ifndef _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000056 try
57 {
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000058#endif // _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000059 func();
60 // handler should not return
61 abort_message("terminate_handler unexpectedly returned");
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000062#ifndef _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000063 }
64 catch (...)
65 {
66 // handler should not throw exception
67 abort_message("terminate_handler unexpectedly threw an exception");
68 }
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000069#endif // _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000070}
71
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000072__attribute__((noreturn))
Howard Hinnant2642af92011-12-06 17:51:25 +000073void
74terminate() _NOEXCEPT
75{
Howard Hinnantd6d4c252012-01-31 01:51:15 +000076 // If there might be an uncaught exception
77 using namespace __cxxabiv1;
78 __cxa_eh_globals* globals = __cxa_get_globals_fast();
79 if (globals)
80 {
81 __cxa_exception* exception_header = globals->caughtExceptions;
82 if (exception_header)
83 {
84 _Unwind_Exception* unwind_exception =
85 reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
Marshall Clow611a55a2018-10-10 16:18:37 +000086 if (__isOurExceptionClass(unwind_exception))
Howard Hinnantd6d4c252012-01-31 01:51:15 +000087 __terminate(exception_header->terminateHandler);
Howard Hinnantd6d4c252012-01-31 01:51:15 +000088 }
89 }
Howard Hinnant2642af92011-12-06 17:51:25 +000090 __terminate(get_terminate());
91}
92
Saleem Abdulrasool51f0c202017-01-04 05:45:24 +000093extern "C" {
Shoaib Meenaife989a92017-03-01 03:55:57 +000094new_handler __cxa_new_handler = 0;
Saleem Abdulrasool51f0c202017-01-04 05:45:24 +000095}
Howard Hinnant4ac72dd2012-03-19 16:20:34 +000096
Howard Hinnant2642af92011-12-06 17:51:25 +000097new_handler
98set_new_handler(new_handler handler) _NOEXCEPT
99{
Eli Friedman17a47b92018-04-16 22:00:14 +0000100 return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel);
Howard Hinnant2642af92011-12-06 17:51:25 +0000101}
102
103new_handler
104get_new_handler() _NOEXCEPT
105{
Eli Friedman17a47b92018-04-16 22:00:14 +0000106 return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire);
Howard Hinnant2642af92011-12-06 17:51:25 +0000107}
108
109} // std