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