Mercurial > hg > CbC > CbC_llvm
comparison libcxxabi/src/cxa_default_handlers.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 2e18cbf3894f |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 //===------------------------- cxa_default_handlers.cpp -------------------===// | |
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-exception | |
6 // | |
7 // | |
8 // This file implements the default terminate_handler and unexpected_handler. | |
9 //===----------------------------------------------------------------------===// | |
10 | |
11 #include <exception> | |
12 #include <stdlib.h> | |
13 #include "abort_message.h" | |
14 #include "cxxabi.h" | |
15 #include "cxa_handlers.h" | |
16 #include "cxa_exception.h" | |
17 #include "private_typeinfo.h" | |
18 #include "include/atomic_support.h" | |
19 | |
20 #if !defined(LIBCXXABI_SILENT_TERMINATE) | |
21 | |
22 _LIBCPP_SAFE_STATIC | |
23 static const char* cause = "uncaught"; | |
24 | |
25 __attribute__((noreturn)) | |
26 static void demangling_terminate_handler() | |
27 { | |
28 #ifndef _LIBCXXABI_NO_EXCEPTIONS | |
29 // If there might be an uncaught exception | |
30 using namespace __cxxabiv1; | |
31 __cxa_eh_globals* globals = __cxa_get_globals_fast(); | |
32 if (globals) | |
33 { | |
34 __cxa_exception* exception_header = globals->caughtExceptions; | |
35 // If there is an uncaught exception | |
36 if (exception_header) | |
37 { | |
38 _Unwind_Exception* unwind_exception = | |
39 reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; | |
40 if (__isOurExceptionClass(unwind_exception)) | |
41 { | |
42 void* thrown_object = | |
43 __getExceptionClass(unwind_exception) == kOurDependentExceptionClass ? | |
44 ((__cxa_dependent_exception*)exception_header)->primaryException : | |
45 exception_header + 1; | |
46 const __shim_type_info* thrown_type = | |
47 static_cast<const __shim_type_info*>(exception_header->exceptionType); | |
48 // Try to get demangled name of thrown_type | |
49 int status; | |
50 char buf[1024]; | |
51 size_t len = sizeof(buf); | |
52 const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status); | |
53 if (status != 0) | |
54 name = thrown_type->name(); | |
55 // If the uncaught exception can be caught with std::exception& | |
56 const __shim_type_info* catch_type = | |
57 static_cast<const __shim_type_info*>(&typeid(std::exception)); | |
58 if (catch_type->can_catch(thrown_type, thrown_object)) | |
59 { | |
60 // Include the what() message from the exception | |
61 const std::exception* e = static_cast<const std::exception*>(thrown_object); | |
62 abort_message("terminating with %s exception of type %s: %s", | |
63 cause, name, e->what()); | |
64 } | |
65 else | |
66 // Else just note that we're terminating with an exception | |
67 abort_message("terminating with %s exception of type %s", | |
68 cause, name); | |
69 } | |
70 else | |
71 // Else we're terminating with a foreign exception | |
72 abort_message("terminating with %s foreign exception", cause); | |
73 } | |
74 } | |
75 #endif | |
76 // Else just note that we're terminating | |
77 abort_message("terminating"); | |
78 } | |
79 | |
80 __attribute__((noreturn)) | |
81 static void demangling_unexpected_handler() | |
82 { | |
83 cause = "unexpected"; | |
84 std::terminate(); | |
85 } | |
86 | |
87 static constexpr std::terminate_handler default_terminate_handler = demangling_terminate_handler; | |
88 static constexpr std::terminate_handler default_unexpected_handler = demangling_unexpected_handler; | |
89 #else | |
90 static constexpr std::terminate_handler default_terminate_handler = ::abort; | |
91 static constexpr std::terminate_handler default_unexpected_handler = std::terminate; | |
92 #endif | |
93 | |
94 // | |
95 // Global variables that hold the pointers to the current handler | |
96 // | |
97 _LIBCXXABI_DATA_VIS | |
98 _LIBCPP_SAFE_STATIC std::terminate_handler __cxa_terminate_handler = default_terminate_handler; | |
99 | |
100 _LIBCXXABI_DATA_VIS | |
101 _LIBCPP_SAFE_STATIC std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler; | |
102 | |
103 namespace std | |
104 { | |
105 | |
106 unexpected_handler | |
107 set_unexpected(unexpected_handler func) _NOEXCEPT | |
108 { | |
109 if (func == 0) | |
110 func = default_unexpected_handler; | |
111 return __libcpp_atomic_exchange(&__cxa_unexpected_handler, func, | |
112 _AO_Acq_Rel); | |
113 } | |
114 | |
115 terminate_handler | |
116 set_terminate(terminate_handler func) _NOEXCEPT | |
117 { | |
118 if (func == 0) | |
119 func = default_terminate_handler; | |
120 return __libcpp_atomic_exchange(&__cxa_terminate_handler, func, | |
121 _AO_Acq_Rel); | |
122 } | |
123 | |
124 } |