1/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3#ident "$Id$"
4/*======
5This file is part of PerconaFT.
6
7
8Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 PerconaFT is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 PerconaFT is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
21
22----------------------------------------
23
24 PerconaFT is free software: you can redistribute it and/or modify
25 it under the terms of the GNU Affero General Public License, version 3,
26 as published by the Free Software Foundation.
27
28 PerconaFT is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU Affero General Public License for more details.
32
33 You should have received a copy of the GNU Affero General Public License
34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
35======= */
36
37#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38
39#pragma once
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <signal.h>
44#include "toku_assert.h"
45
46//Simulate as hard a crash as possible.
47//Choices:
48// raise(SIGABRT)
49// kill -SIGKILL $pid
50// divide by 0
51// null dereference
52// abort()
53// assert(false) (from <assert.h>)
54// assert(false) (from <toku_assert.h>)
55//
56//Linux:
57// abort() and both assert(false) cause FILE buffers to be flushed and written to disk: Unacceptable
58//
59//kill -SIGKILL $pid is annoying (and so far untested)
60//
61//raise(SIGABRT) has the downside that perhaps it could be caught?
62//I'm choosing raise(SIGABRT), followed by divide by 0, followed by null dereference, followed by all the others just in case one gets caught.
63static void __attribute__((unused, noreturn))
64toku_hard_crash_on_purpose(void) {
65 raise(SIGKILL); //Does not flush buffers on linux; cannot be caught.
66 {
67 int zero = 0;
68 int infinity = 1/zero;
69 fprintf(stderr, "Force use of %d\n", infinity);
70 fflush(stderr); //Make certain the string is calculated.
71 }
72 {
73 void * intothevoid = NULL;
74 (*(int*)intothevoid)++;
75 fprintf(stderr, "Force use of *(%p) = %d\n", intothevoid, *(int*)intothevoid);
76 fflush(stderr);
77 }
78 abort();
79 fprintf(stderr, "This line should never be printed\n");
80 fflush(stderr);
81}
82
83// Similar to toku_hard_crash_on_purpose, but the goal isn't to crash hard, the primary goal is to get a corefile, the secondary goal is to terminate in any way possible.
84// We don't really care if buffers get flushed etc, in fact they may as well flush since there may be useful output in stdout or stderr.
85//
86// By default, the following signals generate cores:
87// Linux, from signal(7):
88// SIGQUIT 3 Core
89// SIGILL 4 Core
90// SIGABRT 6 Core
91// SIGFPE 8 Core
92// SIGSEGV 11 Core
93//
94// Darwin and FreeBSD, from signal(3):
95// 3 SIGQUIT create core image
96// 4 SIGILL create core image
97// 5 SIGTRAP create core image
98// 6 SIGABRT create core image
99// 7 SIGEMT create core image
100// 8 SIGFPE create core image
101// 10 SIGBUS create core image
102// 11 SIGSEGV create core image
103// 12 SIGSYS create core image
104//
105// We'll raise these in some sequence (common ones first), then try emulating the things that would cause these signals to be raised, then eventually just try to die normally and then loop like abort does.
106// Start with a toku assert because that hopefully prints a stacktrace.
107static void __attribute__((unused, noreturn))
108toku_crash_and_dump_core_on_purpose(void) {
109 assert(false);
110 invariant(0);
111 raise(SIGQUIT);
112 raise(SIGILL);
113 raise(SIGABRT);
114 raise(SIGFPE);
115 raise(SIGSEGV);
116#if defined(__FreeBSD__) || defined(__APPLE__)
117 raise(SIGTRAP);
118 raise(SIGEMT);
119 raise(SIGBUS);
120 raise(SIGSYS);
121#endif
122 abort();
123 {
124 int zero = 0;
125 int infinity = 1/zero;
126 fprintf(stderr, "Force use of %d\n", infinity);
127 fflush(stderr); //Make certain the string is calculated.
128 }
129 {
130 void * intothevoid = NULL;
131 (*(int*)intothevoid)++;
132 fprintf(stderr, "Force use of *(%p) = %d\n", intothevoid, *(int*)intothevoid);
133 fflush(stderr);
134 }
135 raise(SIGKILL);
136 while (true) {
137 // don't return
138 }
139}
140
141void toku_try_gdb_stack_trace(const char *gdb_path);
142