1439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//===------------------------- cxa_default_handlers.cpp -------------------===//
2439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//
3439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//                     The LLVM Compiler Infrastructure
4439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//
5439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik// This file is dual licensed under the MIT and the University of Illinois Open
6439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik// Source Licenses. See LICENSE.TXT for details.
7439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//
8439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//
9439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik// This file implements the default terminate_handler and unexpected_handler.
10439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//===----------------------------------------------------------------------===//
11439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik
12439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include <stdexcept>
13439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include <new>
14439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include <exception>
150ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knight#include <cstdlib>
16439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include "abort_message.h"
17439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include "cxxabi.h"
18439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include "cxa_handlers.hpp"
19439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include "cxa_exception.hpp"
20439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik#include "private_typeinfo.h"
21439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik
229a02f50fc1d2acde806c69085ad979a685cb0694Peter Collingbourne#if !defined(LIBCXXABI_SILENT_TERMINATE)
23cba79c6fd9380becbc72a0b85ffa5fc354690e9bHoward Hinnantstatic const char* cause = "uncaught";
24cba79c6fd9380becbc72a0b85ffa5fc354690e9bHoward Hinnant
25439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik__attribute__((noreturn))
260ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knightstatic void demangling_terminate_handler()
27439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik{
28439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    // If there might be an uncaught exception
29439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    using namespace __cxxabiv1;
30439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    __cxa_eh_globals* globals = __cxa_get_globals_fast();
31439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    if (globals)
32439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    {
33439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik        __cxa_exception* exception_header = globals->caughtExceptions;
34439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik        // If there is an uncaught exception
35439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik        if (exception_header)
36439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik        {
37439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik            _Unwind_Exception* unwind_exception =
38439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
39439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik            bool native_exception =
40439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                (unwind_exception->exception_class   & get_vendor_and_language) ==
41439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                                 (kOurExceptionClass & get_vendor_and_language);
42439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik            if (native_exception)
43439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik            {
44439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                void* thrown_object =
45439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    unwind_exception->exception_class == kOurDependentExceptionClass ?
46439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                        ((__cxa_dependent_exception*)exception_header)->primaryException :
47439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                        exception_header + 1;
48439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                const __shim_type_info* thrown_type =
49439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    static_cast<const __shim_type_info*>(exception_header->exceptionType);
50439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                // Try to get demangled name of thrown_type
51439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                int status;
52439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                char buf[1024];
53439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                size_t len = sizeof(buf);
54439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status);
55439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                if (status != 0)
56439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    name = thrown_type->name();
57439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                // If the uncaught exception can be caught with std::exception&
58439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                const __shim_type_info* catch_type =
59439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik				 static_cast<const __shim_type_info*>(&typeid(std::exception));
60439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                if (catch_type->can_catch(thrown_type, thrown_object))
61439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                {
62439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    // Include the what() message from the exception
63439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    const std::exception* e = static_cast<const std::exception*>(thrown_object);
64439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    abort_message("terminating with %s exception of type %s: %s",
65439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                                  cause, name, e->what());
66439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                }
67439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                else
68439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    // Else just note that we're terminating with an exception
69439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                    abort_message("terminating with %s exception of type %s",
70439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                                   cause, name);
71439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik            }
72439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik            else
73439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                // Else we're terminating with a foreign exception
74439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik                abort_message("terminating with %s foreign exception", cause);
75439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik        }
76439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    }
77439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    // Else just note that we're terminating
78439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik    abort_message("terminating");
79439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik}
80439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik
810f80bb79c0181c706cf6acce44f854e96ecaf755Howard Hinnant__attribute__((noreturn))
820ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knightstatic void demangling_unexpected_handler()
83439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik{
84cba79c6fd9380becbc72a0b85ffa5fc354690e9bHoward Hinnant    cause = "unexpected";
85cba79c6fd9380becbc72a0b85ffa5fc354690e9bHoward Hinnant    std::terminate();
86439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik}
87439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik
880ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knightstatic std::terminate_handler default_terminate_handler = demangling_terminate_handler;
890ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knightstatic std::terminate_handler default_unexpected_handler = demangling_unexpected_handler;
900ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knight#else
910ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knightstatic std::terminate_handler default_terminate_handler = std::abort;
92a3b0b11e68329c57be7059f61a4f3f52302e9bd0Asiri Rathnayakestatic std::terminate_handler default_unexpected_handler = std::terminate;
930ecfd76f83e8388125b6dca6a99efb2823c7e940James Y Knight#endif
94439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik
95439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//
96439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik// Global variables that hold the pointers to the current handler
97439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzik//
98436072f52ff05d69f626a9c7a309a1464758f129Saleem Abdulrasool_LIBCXXABI_DATA_VIS
99436072f52ff05d69f626a9c7a309a1464758f129Saleem Abdulrasoolstd::terminate_handler __cxa_terminate_handler = default_terminate_handler;
100436072f52ff05d69f626a9c7a309a1464758f129Saleem Abdulrasool
101436072f52ff05d69f626a9c7a309a1464758f129Saleem Abdulrasool_LIBCXXABI_DATA_VIS
102439ce87946c310a093f4d39a2636ce6b4682bdacNick Kledzikstd::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler;
1032507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki
1044cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant// In the future these will become:
1054cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant// std::atomic<std::terminate_handler>  __cxa_terminate_handler(default_terminate_handler);
1064cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant// std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler);
1074cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant
1082507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzyckinamespace std
1092507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki{
1102507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki
1112507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzyckiunexpected_handler
1122507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzyckiset_unexpected(unexpected_handler func) _NOEXCEPT
1132507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki{
1145660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner    if (func == 0)
1155660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner        func = default_unexpected_handler;
1165660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner    return __atomic_exchange_n(&__cxa_unexpected_handler, func,
1175660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner                               __ATOMIC_ACQ_REL);
1184cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant//  Using of C++11 atomics this should be rewritten
1194cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant//  return __cxa_unexpected_handler.exchange(func, memory_order_acq_rel);
1202507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki}
1212507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki
1222507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzyckiterminate_handler
1232507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzyckiset_terminate(terminate_handler func) _NOEXCEPT
1242507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki{
1255660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner    if (func == 0)
1265660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner        func = default_terminate_handler;
1275660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner    return __atomic_exchange_n(&__cxa_terminate_handler, func,
1285660f752e7eebc1b2cfd62ed1c1c12da75efc727Reid Kleckner                               __ATOMIC_ACQ_REL);
1294cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant//  Using of C++11 atomics this should be rewritten
1304cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant//  return __cxa_terminate_handler.exchange(func, memory_order_acq_rel);
1312507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki}
1322507beff620a5d748de01b83bb8f33adcb228c0eDave Zarzycki
1334cfb63f07516ceff10be81c7dfac6c18122df782Howard Hinnant}
134