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 <cxxabi.h> 30 #include <exception> 31 32 namespace std { 33 34 namespace { 35 // The default std::terminate() implementation will crash the process. 36 // This is done to help debugging, i.e.: 37 // - When running the program in a debugger, it's trivial to get 38 // a complete stack trace explaining the failure. 39 // 40 // - Otherwise, the default SIGSEGV handler will generate a stack 41 // trace in the log, that can later be processed with ndk-stack 42 // and other tools. 43 // 44 // - Finally, this also works when a custom SIGSEGV handler has been 45 // installed. E.g. when using Google Breakpad, the termination will 46 // be recorded in a Minidump, which contains a stack trace to be 47 // later analyzed. 48 // 49 // The C++ specification states that the default std::terminate() 50 // handler is library-specific, even though most implementation simply 51 // choose to call abort() in this case. 52 // 53 void default_terminate(void) { 54 // The crash address is just a "magic" constant that can be used to 55 // identify stack traces (like 0xdeadbaad is used when heap corruption 56 // is detected in the C library). 'cab1' stands for "C++ ABI" :-) 57 *(reinterpret_cast<char*>(0xdeadcab1)) = 0; 58 59 // should not be here, but just in case. 60 abort(); 61 } 62 63 terminate_handler current_terminate_fn = default_terminate; 64 unexpected_handler current_unexpected_fn = terminate; 65 } // namespace 66 67 #if !defined(GABIXX_LIBCXX) 68 exception::exception() throw() { 69 } 70 #endif // !defined(GABIXX_LIBCXX) 71 72 exception::~exception() throw() { 73 } 74 75 const char* exception::what() const throw() { 76 return "std::exception"; 77 } 78 79 #if !defined(GABIXX_LIBCXX) 80 bad_exception::bad_exception() throw() { 81 } 82 83 bad_exception::~bad_exception() throw() { 84 } 85 86 const char* bad_exception::what() const throw() { 87 return "std::bad_exception"; 88 } 89 #endif // !defined(GABIXX_LIBCXX) 90 91 bad_cast::bad_cast() throw() { 92 } 93 94 bad_cast::~bad_cast() throw() { 95 } 96 97 const char* bad_cast::what() const throw() { 98 return "std::bad_cast"; 99 } 100 101 bad_typeid::bad_typeid() throw() { 102 } 103 104 bad_typeid::~bad_typeid() throw() { 105 } 106 107 const char* bad_typeid::what() const throw() { 108 return "std::bad_typeid"; 109 } 110 111 terminate_handler get_terminate() { 112 return current_terminate_fn; 113 } 114 115 terminate_handler set_terminate(terminate_handler f) { 116 terminate_handler tmp = current_terminate_fn; 117 current_terminate_fn = f; 118 return tmp; 119 } 120 121 void terminate() { 122 try { 123 current_terminate_fn(); 124 abort(); 125 } catch (...) { 126 abort(); 127 } 128 } 129 130 unexpected_handler get_unexpected() { 131 return current_unexpected_fn; 132 } 133 134 unexpected_handler set_unexpected(unexpected_handler f) { 135 unexpected_handler tmp = current_unexpected_fn; 136 current_unexpected_fn = f; 137 return tmp; 138 } 139 140 void unexpected() { 141 current_unexpected_fn(); 142 terminate(); 143 } 144 145 bool uncaught_exception() throw() { 146 using namespace __cxxabiv1; 147 148 __cxa_eh_globals* globals = __cxa_get_globals(); 149 return globals->uncaughtExceptions != 0; 150 } 151 152 } // namespace std 153