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(&current_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(&current_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(&current_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(&current_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