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 32 namespace { 33 34 std::terminate_handler current_terminate = __gabixx::__default_terminate; 35 std::unexpected_handler current_unexpected = __gabixx::__default_terminate; 36 37 } // namespace 38 39 40 namespace __gabixx { 41 42 // The default std::terminate() implementation will crash the process. 43 // This is done to help debugging, i.e.: 44 // - When running the program in a debugger, it's trivial to get 45 // a complete stack trace explaining the failure. 46 // 47 // - Otherwise, the default SIGSEGV handler will generate a stack 48 // trace in the log, that can later be processed with ndk-stack 49 // and other tools. 50 // 51 // - Finally, this also works when a custom SIGSEGV handler has been 52 // installed. E.g. when using Google Breakpad, the termination will 53 // be recorded in a Minidump, which contains a stack trace to be 54 // later analyzed. 55 // 56 // The C++ specification states that the default std::terminate() 57 // handler is library-specific, even though most implementation simply 58 // choose to call abort() in this case. 59 // 60 _GABIXX_NORETURN void __default_terminate(void) { 61 // The crash address is just a "magic" constant that can be used to 62 // identify stack traces (like 0xdeadbaad is used when heap corruption 63 // is detected in the C library). 'cab1' stands for "C++ ABI" :-) 64 *(reinterpret_cast<char*>(0xdeadcab1)) = 0; 65 66 // should not be here, but just in case. 67 abort(); 68 } 69 70 _GABIXX_NORETURN void __terminate(std::terminate_handler handler) { 71 if (!handler) 72 handler = __default_terminate; 73 74 #if _GABIXX_HAS_EXCEPTIONS 75 try { 76 (*handler)(); 77 } catch (...) { 78 /* nothing */ 79 } 80 #else 81 (*handler)(); 82 #endif 83 __default_terminate(); 84 } 85 86 } // namespace __gabixx 87 88 namespace std { 89 90 terminate_handler get_terminate() { 91 return __gabixx_sync_load(¤t_terminate); 92 } 93 94 terminate_handler set_terminate(terminate_handler f) { 95 if (!f) 96 f = __gabixx::__default_terminate; 97 98 return __gabixx_sync_swap(¤t_terminate, f); 99 } 100 101 _GABIXX_NORETURN void terminate() { 102 __gabixx::__terminate(std::get_terminate()); 103 } 104 105 unexpected_handler get_unexpected() { 106 return __gabixx_sync_load(¤t_unexpected); 107 } 108 109 unexpected_handler set_unexpected(unexpected_handler f) { 110 if (!f) 111 f = __gabixx::__default_terminate; 112 113 return __gabixx_sync_swap(¤t_unexpected, f); 114 } 115 116 _GABIXX_NORETURN void unexpected() { 117 (*get_unexpected())(); 118 terminate(); 119 } 120 121 } // namespace std 122