1// Copyright (C) 2012 The Android Open Source Project 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 1. Redistributions of source code must retain the above copyright 8// notice, this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright 10// notice, this list of conditions and the following disclaimer in the 11// documentation and/or other materials provided with the distribution. 12// 3. Neither the name of the project nor the names of its contributors 13// may be used to endorse or promote products derived from this software 14// without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26// SUCH DAMAGE. 27 28#include <cstdlib> 29#include <exception> 30#include "cxxabi_defines.h" 31 32namespace { 33 34std::terminate_handler current_terminate = __gabixx::__default_terminate; 35std::unexpected_handler current_unexpected = __gabixx::__default_unexpected; 36 37} // namespace 38 39 40namespace __gabixx { 41 42// The default std::unexpected() implementation will delegate to 43// std::terminate() so that the user-defined std::terminate() handler can 44// get the chance to be invoked. 45// 46_GABIXX_NORETURN void __default_unexpected(void) { 47 std::terminate(); 48} 49 50// The default std::terminate() implementation will crash the process. 51// This is done to help debugging, i.e.: 52// - When running the program in a debugger, it's trivial to get 53// a complete stack trace explaining the failure. 54// 55// - Otherwise, the default SIGSEGV handler will generate a stack 56// trace in the log, that can later be processed with ndk-stack 57// and other tools. 58// 59// - Finally, this also works when a custom SIGSEGV handler has been 60// installed. E.g. when using Google Breakpad, the termination will 61// be recorded in a Minidump, which contains a stack trace to be 62// later analyzed. 63// 64// The C++ specification states that the default std::terminate() 65// handler is library-specific, even though most implementation simply 66// choose to call abort() in this case. 67// 68_GABIXX_NORETURN void __default_terminate(void) { 69 // The crash address is just a "magic" constant that can be used to 70 // identify stack traces (like 0xdeadbaad is used when heap corruption 71 // is detected in the C library). 'cab1' stands for "C++ ABI" :-) 72 *(reinterpret_cast<char*>(0xdeadcab1)) = 0; 73 74 // should not be here, but just in case. 75 abort(); 76} 77 78_GABIXX_NORETURN void __terminate(std::terminate_handler handler) { 79 if (!handler) 80 handler = __default_terminate; 81 82#if _GABIXX_HAS_EXCEPTIONS 83 try { 84 (*handler)(); 85 } catch (...) { 86 /* nothing */ 87 } 88#else 89 (*handler)(); 90#endif 91 __default_terminate(); 92} 93 94} // namespace __gabixx 95 96namespace std { 97 98terminate_handler get_terminate() _GABIXX_NOEXCEPT { 99 return __gabixx_sync_load(¤t_terminate); 100} 101 102terminate_handler set_terminate(terminate_handler f) _GABIXX_NOEXCEPT { 103 if (!f) 104 f = __gabixx::__default_terminate; 105 106 return __gabixx_sync_swap(¤t_terminate, f); 107} 108 109_GABIXX_NORETURN void terminate() _GABIXX_NOEXCEPT_CXX11_ONLY { 110 __gabixx::__terminate(std::get_terminate()); 111} 112 113unexpected_handler get_unexpected() _GABIXX_NOEXCEPT { 114 return __gabixx_sync_load(¤t_unexpected); 115} 116 117unexpected_handler set_unexpected(unexpected_handler f) _GABIXX_NOEXCEPT { 118 if (!f) 119 f = __gabixx::__default_terminate; 120 121 return __gabixx_sync_swap(¤t_unexpected, f); 122} 123 124_GABIXX_NORETURN void unexpected() { 125 unexpected_handler handler = std::get_unexpected(); 126 if (handler) 127 (*handler)(); 128 129 // If the handler returns, then call terminate(). 130 terminate(); 131} 132 133} // namespace std 134