-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtermination_handler.cpp
98 lines (88 loc) · 3.01 KB
/
termination_handler.cpp
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
#include "termination_handler.hpp"
#include "log.hpp"
#include "filesystem/filesystem.hpp"
#include <cxxabi.h>
#include <thread>
#include <chrono>
#include <fstream>
#include <sstream>
#ifndef WINDOWS
# include <signal.h>
#endif
#define BOOST_STACKTRACE_USE_BACKTRACE
#include <boost/stacktrace.hpp>
//#####################################################################################################################
[[noreturn]] void onTerminate() noexcept
{
if (auto exc = std::current_exception())
{
// we have an exception
LOG() << "uncaught exception in terminate handler: \n";
int status;
LOGEX(false) << '\t' << abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), 0, 0, &status) << "\n";
std::stringstream sstr;
LOGEX(false) << "-------------\n";
sstr << boost::stacktrace::stacktrace();
sstr << sstr.str() << "\n";
LOGEX(false) << "-------------\n";
try
{
rethrow_exception(exc); // throw to recognize the type
}
catch (std::exception const& exc)
{
LOGEX(false) << '\t' << exc.what() << "\n";
}
catch (...)
{
LOGEX(false) << "WARNING! This is not a derivative of std::exception" << "\n";
LOGEX(false) << "This is a severe error" << "\n";
// additional action
}
std::_Exit(EXIT_FAILURE);
}
std::_Exit(EXIT_FAILURE);
}
//---------------------------------------------------------------------------------------------------------------------
[[noreturn]] void onBadSignal(int signal) noexcept
{
boost::stacktrace::safe_dump_to("./backtrace.dump");
LOG() << "handling signal: ";
switch (signal)
{
case SIGABRT:
LOGEX(false) << "SIGABRT\n";
break;
case SIGFPE:
LOGEX(false) << "SIGFPE\n";
break;
case SIGILL:
LOGEX(false) << "SIGILL\n";
break;
case SIGSEGV:
LOGEX(false) << "SIGSEGV\n";
break;
}
std::stringstream sstr;
LOGEX(false) << "-------------\n";
sstr << boost::stacktrace::stacktrace();
LOGEX(false) << sstr.str();
LOGEX(false) << "-------------\n";
std::_Exit(EXIT_FAILURE);
}
//---------------------------------------------------------------------------------------------------------------------
void parseAndLogPreviousDump()
{
if (sfs::exists("./backtrace.dump"))
{
std::ifstream ifs("./backtrace.dump");
boost::stacktrace::stacktrace st = boost::stacktrace::stacktrace::from_dump(ifs);
std::stringstream sstr;
sstr << "Previous run crashed:\n" << st << std::endl;
LOG() << sstr.str();
// cleaning up
ifs.close();
sfs::remove("./backtrace.dump");
}
}
//#####################################################################################################################