forked from etotheipi/BitcoinArmory
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsighandler.cpp
More file actions
105 lines (88 loc) · 2.68 KB
/
sighandler.cpp
File metadata and controls
105 lines (88 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2011-2015, Armory Technologies, Inc. //
// Distributed under the GNU Affero General Public License (AGPL v3) //
// See LICENSE or http://www.gnu.org/licenses/agpl.html //
// //
////////////////////////////////////////////////////////////////////////////////
#ifdef __linux__
#include "log.h"
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static void sigsegv(int, siginfo_t *info, void*)
{
const int stderr=2;
{
const char e1[] =
"\nArmory has crashed. Please provide the following "
"in your bug report:\n"
"Failed to dereference address ";
::write(stderr, e1, sizeof(e1)-1);
}
{
char addr[64];
int num = snprintf(addr, sizeof(addr), "%p", info->si_addr);
::write(stderr, addr, num);
::write(stderr, "\n", 1);
}
void* bt_buffer[64];
int n = backtrace(bt_buffer, sizeof(bt_buffer)/sizeof(bt_buffer[0]));
backtrace_symbols_fd(bt_buffer, n, stderr);
// allow crash again, so that the user sees the pretty "Segmentation fault"
signal(SIGSEGV, 0);
// now try to write that same error to the log file
// since Log::filename accesses what might be corrupt memory,
// we have to repeat some of the stuff above. So it can crash
// here and we still get a log on stderr
int log = open(Log::filename().c_str(), O_APPEND, O_WRONLY);
if (log != -1)
{
{
const char e1[] =
"\n\nSIGSEGV\n"
"Failed to dereference address ";
::write(log, e1, sizeof(e1)-1);
}
{
char addr[64];
int num = snprintf(addr, sizeof(addr), "%p", info->si_addr);
::write(log, addr, num);
::write(log, "\n", 1);
}
backtrace_symbols_fd(bt_buffer, n, log);
::close(log);
}
// now actually crash again so the user sees the error
int *crash = (int*)0;
*crash = 0;
}
static void installSignalHandler()
{
static bool installed=false;
if (installed)
return;
installed = true;
struct sigaction action;
action.sa_sigaction = sigsegv;
action.sa_flags = SA_SIGINFO | SA_NODEFER;
sigaction(SIGSEGV, &action, 0);
}
namespace
{
class Init
{
public:
Init()
{
installSignalHandler();
}
};
}
static Init install;
// kate: indent-width 3; replace-tabs on;
#endif