blob: 8c26bd0b1a6b043790ac0e073edaf0d03527a5f2 [file] [log] [blame]
Howard Hinnant2642af92011-12-06 17:51:25 +00001//===------------------------- cxa_handlers.cpp ---------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//
9// This file implements the functionality associated with the terminate_handler,
10// unexpected_handler, and new_handler.
11//===----------------------------------------------------------------------===//
12
13#include <stdexcept>
14#include <new>
15#include <exception>
16#include "abort_message.h"
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000017#include "cxxabi.h"
Howard Hinnant5ec91832011-12-07 21:16:40 +000018#include "cxa_handlers.hpp"
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000019#include "cxa_exception.hpp"
20#include "private_typeinfo.h"
Eli Friedman17a47b92018-04-16 22:00:14 +000021#include "include/atomic_support.h"
Howard Hinnant2642af92011-12-06 17:51:25 +000022
23namespace std
24{
25
Howard Hinnant2642af92011-12-06 17:51:25 +000026unexpected_handler
27get_unexpected() _NOEXCEPT
28{
Eli Friedman17a47b92018-04-16 22:00:14 +000029 return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);
Howard Hinnant2642af92011-12-06 17:51:25 +000030}
31
Howard Hinnant2642af92011-12-06 17:51:25 +000032void
33__unexpected(unexpected_handler func)
34{
35 func();
36 // unexpected handler should not return
37 abort_message("unexpected_handler unexpectedly returned");
38}
39
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000040__attribute__((noreturn))
Howard Hinnant2642af92011-12-06 17:51:25 +000041void
42unexpected()
43{
44 __unexpected(get_unexpected());
45}
46
47terminate_handler
Howard Hinnant2642af92011-12-06 17:51:25 +000048get_terminate() _NOEXCEPT
49{
Eli Friedman17a47b92018-04-16 22:00:14 +000050 return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);
Howard Hinnant2642af92011-12-06 17:51:25 +000051}
52
Howard Hinnant2642af92011-12-06 17:51:25 +000053void
54__terminate(terminate_handler func) _NOEXCEPT
55{
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000056#ifndef _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000057 try
58 {
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000059#endif // _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000060 func();
61 // handler should not return
62 abort_message("terminate_handler unexpectedly returned");
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000063#ifndef _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000064 }
65 catch (...)
66 {
67 // handler should not throw exception
68 abort_message("terminate_handler unexpectedly threw an exception");
69 }
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000070#endif // _LIBCXXABI_NO_EXCEPTIONS
Howard Hinnant2642af92011-12-06 17:51:25 +000071}
72
Howard Hinnanta9d8ec42012-01-24 18:26:29 +000073__attribute__((noreturn))
Howard Hinnant2642af92011-12-06 17:51:25 +000074void
75terminate() _NOEXCEPT
76{
Howard Hinnantd6d4c252012-01-31 01:51:15 +000077 // If there might be an uncaught exception
78 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;
Marshall Clow611a55a2018-10-10 16:18:37 +000087 if (__isOurExceptionClass(unwind_exception))
Howard Hinnantd6d4c252012-01-31 01:51:15 +000088 __terminate(exception_header->terminateHandler);
Howard Hinnantd6d4c252012-01-31 01:51:15 +000089 }
90 }
Howard Hinnant2642af92011-12-06 17:51:25 +000091 __terminate(get_terminate());
92}
93
Saleem Abdulrasool51f0c202017-01-04 05:45:24 +000094extern "C" {
Shoaib Meenaife989a92017-03-01 03:55:57 +000095new_handler __cxa_new_handler = 0;
Saleem Abdulrasool51f0c202017-01-04 05:45:24 +000096}
Howard Hinnant4ac72dd2012-03-19 16:20:34 +000097
Howard Hinnant2642af92011-12-06 17:51:25 +000098new_handler
99set_new_handler(new_handler handler) _NOEXCEPT
100{
Eli Friedman17a47b92018-04-16 22:00:14 +0000101 return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel);
Howard Hinnant2642af92011-12-06 17:51:25 +0000102}
103
104new_handler
105get_new_handler() _NOEXCEPT
106{
Eli Friedman17a47b92018-04-16 22:00:14 +0000107 return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire);
Howard Hinnant2642af92011-12-06 17:51:25 +0000108}
109
110} // std