annotate libcxxabi/src/cxa_default_handlers.cpp @ 266:00f31e85ec16 default tip

Added tag current for changeset 31d058e83c98
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 14 Oct 2023 10:13:55 +0900
parents c4bab56944e8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
1 //===----------------------------------------------------------------------===//
150
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
8 // This file implements the default terminate_handler, unexpected_handler and
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
9 // new_handler.
150
anatofuz
parents:
diff changeset
10 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 #include <exception>
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
13 #include <memory>
150
anatofuz
parents:
diff changeset
14 #include <stdlib.h>
anatofuz
parents:
diff changeset
15 #include "abort_message.h"
anatofuz
parents:
diff changeset
16 #include "cxxabi.h"
anatofuz
parents:
diff changeset
17 #include "cxa_handlers.h"
anatofuz
parents:
diff changeset
18 #include "cxa_exception.h"
anatofuz
parents:
diff changeset
19 #include "private_typeinfo.h"
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
20 #include "include/atomic_support.h" // from libc++
150
anatofuz
parents:
diff changeset
21
anatofuz
parents:
diff changeset
22 #if !defined(LIBCXXABI_SILENT_TERMINATE)
anatofuz
parents:
diff changeset
23
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
24 static constinit const char* cause = "uncaught";
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
25
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
26 #ifndef _LIBCXXABI_NO_EXCEPTIONS
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
27 // Demangle the given string, or return the string as-is in case of an error.
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
28 static std::unique_ptr<char const, void (*)(char const*)> demangle(char const* str)
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
29 {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
30 #if !defined(LIBCXXABI_NON_DEMANGLING_TERMINATE)
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
31 if (const char* result = __cxxabiv1::__cxa_demangle(str, nullptr, nullptr, nullptr))
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
32 return {result, [](char const* p) { std::free(const_cast<char*>(p)); }};
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
33 #endif
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
34 return {str, [](char const*) { /* nothing to free */ }};
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
35 }
150
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 __attribute__((noreturn))
anatofuz
parents:
diff changeset
38 static void demangling_terminate_handler()
anatofuz
parents:
diff changeset
39 {
anatofuz
parents:
diff changeset
40 using namespace __cxxabiv1;
anatofuz
parents:
diff changeset
41 __cxa_eh_globals* globals = __cxa_get_globals_fast();
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
42
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
43 // If there is no uncaught exception, just note that we're terminating
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
44 if (!globals)
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
45 abort_message("terminating");
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
46
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
47 __cxa_exception* exception_header = globals->caughtExceptions;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
48 if (!exception_header)
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
49 abort_message("terminating");
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
50
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
51 _Unwind_Exception* unwind_exception =
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
52 reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
53
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
54 // If we're terminating due to a foreign exception
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
55 if (!__isOurExceptionClass(unwind_exception))
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
56 abort_message("terminating due to %s foreign exception", cause);
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
57
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
58 void* thrown_object =
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
59 __getExceptionClass(unwind_exception) == kOurDependentExceptionClass ?
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
60 ((__cxa_dependent_exception*)exception_header)->primaryException :
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
61 exception_header + 1;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
62 const __shim_type_info* thrown_type =
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
63 static_cast<const __shim_type_info*>(exception_header->exceptionType);
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
64 auto name = demangle(thrown_type->name());
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
65 // If the uncaught exception can be caught with std::exception&
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
66 const __shim_type_info* catch_type =
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
67 static_cast<const __shim_type_info*>(&typeid(std::exception));
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
68 if (catch_type->can_catch(thrown_type, thrown_object))
150
anatofuz
parents:
diff changeset
69 {
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
70 // Include the what() message from the exception
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
71 const std::exception* e = static_cast<const std::exception*>(thrown_object);
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
72 abort_message("terminating due to %s exception of type %s: %s", cause, name.get(), e->what());
150
anatofuz
parents:
diff changeset
73 }
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
74 else
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
75 {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
76 // Else just note that we're terminating due to an exception
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
77 abort_message("terminating due to %s exception of type %s", cause, name.get());
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
78 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
79 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
80 #else // !_LIBCXXABI_NO_EXCEPTIONS
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
81 __attribute__((noreturn))
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
82 static void demangling_terminate_handler()
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
83 {
150
anatofuz
parents:
diff changeset
84 abort_message("terminating");
anatofuz
parents:
diff changeset
85 }
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
86 #endif // !_LIBCXXABI_NO_EXCEPTIONS
150
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 __attribute__((noreturn))
anatofuz
parents:
diff changeset
89 static void demangling_unexpected_handler()
anatofuz
parents:
diff changeset
90 {
anatofuz
parents:
diff changeset
91 cause = "unexpected";
anatofuz
parents:
diff changeset
92 std::terminate();
anatofuz
parents:
diff changeset
93 }
anatofuz
parents:
diff changeset
94
anatofuz
parents:
diff changeset
95 static constexpr std::terminate_handler default_terminate_handler = demangling_terminate_handler;
anatofuz
parents:
diff changeset
96 static constexpr std::terminate_handler default_unexpected_handler = demangling_unexpected_handler;
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
97 #else // !LIBCXXABI_SILENT_TERMINATE
150
anatofuz
parents:
diff changeset
98 static constexpr std::terminate_handler default_terminate_handler = ::abort;
anatofuz
parents:
diff changeset
99 static constexpr std::terminate_handler default_unexpected_handler = std::terminate;
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
100 #endif // !LIBCXXABI_SILENT_TERMINATE
150
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 //
anatofuz
parents:
diff changeset
103 // Global variables that hold the pointers to the current handler
anatofuz
parents:
diff changeset
104 //
anatofuz
parents:
diff changeset
105 _LIBCXXABI_DATA_VIS
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
106 constinit std::terminate_handler __cxa_terminate_handler = default_terminate_handler;
150
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 _LIBCXXABI_DATA_VIS
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
109 constinit std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
110
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
111 _LIBCXXABI_DATA_VIS
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
112 constinit std::new_handler __cxa_new_handler = nullptr;
150
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 namespace std
anatofuz
parents:
diff changeset
115 {
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 unexpected_handler
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
118 set_unexpected(unexpected_handler func) noexcept
150
anatofuz
parents:
diff changeset
119 {
anatofuz
parents:
diff changeset
120 if (func == 0)
anatofuz
parents:
diff changeset
121 func = default_unexpected_handler;
anatofuz
parents:
diff changeset
122 return __libcpp_atomic_exchange(&__cxa_unexpected_handler, func,
anatofuz
parents:
diff changeset
123 _AO_Acq_Rel);
anatofuz
parents:
diff changeset
124 }
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 terminate_handler
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
127 set_terminate(terminate_handler func) noexcept
150
anatofuz
parents:
diff changeset
128 {
anatofuz
parents:
diff changeset
129 if (func == 0)
anatofuz
parents:
diff changeset
130 func = default_terminate_handler;
anatofuz
parents:
diff changeset
131 return __libcpp_atomic_exchange(&__cxa_terminate_handler, func,
anatofuz
parents:
diff changeset
132 _AO_Acq_Rel);
anatofuz
parents:
diff changeset
133 }
anatofuz
parents:
diff changeset
134
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
135 new_handler
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
136 set_new_handler(new_handler handler) noexcept
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
137 {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
138 return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel);
150
anatofuz
parents:
diff changeset
139 }
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
140
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
141 }