diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-09-02 13:41:26 -0600 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-09-06 12:28:19 +0200 |
commit | 323dae6c7fd982f444e1736410888037239e662c (patch) | |
tree | a063bdf5a987123ccfb629398f44c4631855b1ab | |
parent | 2180926301a6417b8dd06dba9d65a337d3e91db1 (diff) | |
download | kube-323dae6c7fd982f444e1736410888037239e662c.tar.gz kube-323dae6c7fd982f444e1736410888037239e662c.zip |
Install a crash handler
..that prints a backtrace on crash.
-rw-r--r-- | applications/kube/CMakeLists.txt | 1 | ||||
-rw-r--r-- | applications/kube/main.cpp | 106 |
2 files changed, 107 insertions, 0 deletions
diff --git a/applications/kube/CMakeLists.txt b/applications/kube/CMakeLists.txt index 2d0df2ad..2d4c9da7 100644 --- a/applications/kube/CMakeLists.txt +++ b/applications/kube/CMakeLists.txt | |||
@@ -21,6 +21,7 @@ target_link_libraries(${PROJECT_NAME} | |||
21 | Qt5::Widgets | 21 | Qt5::Widgets |
22 | Qt5::WebEngine | 22 | Qt5::WebEngine |
23 | KF5::Package | 23 | KF5::Package |
24 | ${CMAKE_DL_LIBS} | ||
24 | ) | 25 | ) |
25 | 26 | ||
26 | install(TARGETS ${PROJECT_NAME} DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) | 27 | install(TARGETS ${PROJECT_NAME} DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) |
diff --git a/applications/kube/main.cpp b/applications/kube/main.cpp index 44897b2e..a6b51c38 100644 --- a/applications/kube/main.cpp +++ b/applications/kube/main.cpp | |||
@@ -17,6 +17,19 @@ | |||
17 | 02110-1301, USA. | 17 | 02110-1301, USA. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <signal.h> | ||
21 | #include <execinfo.h> | ||
22 | #include <csignal> | ||
23 | #include <iostream> | ||
24 | #include <cstdlib> | ||
25 | #include <cxxabi.h> | ||
26 | #include <dlfcn.h> | ||
27 | #include <ostream> | ||
28 | #include <sstream> | ||
29 | #include <thread> | ||
30 | #include <chrono> | ||
31 | #include <unistd.h> | ||
32 | |||
20 | #include <QApplication> | 33 | #include <QApplication> |
21 | #include <QQmlApplicationEngine> | 34 | #include <QQmlApplicationEngine> |
22 | 35 | ||
@@ -28,6 +41,94 @@ | |||
28 | 41 | ||
29 | #include <QDebug> | 42 | #include <QDebug> |
30 | 43 | ||
44 | //Print a demangled stacktrace | ||
45 | void printStacktrace() | ||
46 | { | ||
47 | int skip = 1; | ||
48 | void *callstack[128]; | ||
49 | const int nMaxFrames = sizeof(callstack) / sizeof(callstack[0]); | ||
50 | char buf[1024]; | ||
51 | int nFrames = backtrace(callstack, nMaxFrames); | ||
52 | char **symbols = backtrace_symbols(callstack, nFrames); | ||
53 | |||
54 | std::ostringstream trace_buf; | ||
55 | for (int i = skip; i < nFrames; i++) { | ||
56 | // printf("%s\n", symbols[i]); | ||
57 | Dl_info info; | ||
58 | if (dladdr(callstack[i], &info) && info.dli_sname) { | ||
59 | char *demangled = NULL; | ||
60 | int status = -1; | ||
61 | if (info.dli_sname[0] == '_') { | ||
62 | demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); | ||
63 | } | ||
64 | snprintf(buf, sizeof(buf), "%-3d %*p %s + %zd\n", | ||
65 | i, int(2 + sizeof(void*) * 2), callstack[i], | ||
66 | status == 0 ? demangled : | ||
67 | info.dli_sname == 0 ? symbols[i] : info.dli_sname, | ||
68 | (char *)callstack[i] - (char *)info.dli_saddr); | ||
69 | free(demangled); | ||
70 | } else { | ||
71 | snprintf(buf, sizeof(buf), "%-3d %*p %s\n", | ||
72 | i, int(2 + sizeof(void*) * 2), callstack[i], symbols[i]); | ||
73 | } | ||
74 | trace_buf << buf; | ||
75 | } | ||
76 | free(symbols); | ||
77 | if (nFrames == nMaxFrames) { | ||
78 | trace_buf << "[truncated]\n"; | ||
79 | } | ||
80 | std::cerr << trace_buf.str(); | ||
81 | } | ||
82 | |||
83 | static int sCounter = 0; | ||
84 | |||
85 | void crashHandler(int signal) | ||
86 | { | ||
87 | //Guard against crashing in here | ||
88 | if (sCounter > 1) { | ||
89 | std::_Exit(EXIT_FAILURE); | ||
90 | } | ||
91 | sCounter++; | ||
92 | |||
93 | if (signal == SIGABRT) { | ||
94 | std::cerr << "SIGABRT received\n"; | ||
95 | } else if (signal == SIGSEGV) { | ||
96 | std::cerr << "SIGSEV received\n"; | ||
97 | } else { | ||
98 | std::cerr << "Unexpected signal " << signal << " received\n"; | ||
99 | } | ||
100 | |||
101 | printStacktrace(); | ||
102 | |||
103 | std::fprintf(stdout, "Sleeping for 10s to attach a debugger: gdb attach %i\n", getpid()); | ||
104 | std::this_thread::sleep_for(std::chrono::seconds(10)); | ||
105 | |||
106 | // std::system("exec gdb -p \"$PPID\" -ex \"thread apply all bt\""); | ||
107 | // This only works if we actually have xterm and X11 available | ||
108 | // std::system("exec xterm -e gdb -p \"$PPID\""); | ||
109 | |||
110 | std::_Exit(EXIT_FAILURE); | ||
111 | } | ||
112 | |||
113 | void terminateHandler() | ||
114 | { | ||
115 | // std::exception_ptr exptr = std::current_exception(); | ||
116 | // if (exptr != 0) | ||
117 | // { | ||
118 | // // the only useful feature of std::exception_ptr is that it can be rethrown... | ||
119 | // try { | ||
120 | // std::rethrow_exception(exptr); | ||
121 | // } catch (std::exception &ex) { | ||
122 | // std::fprintf(stderr, "Terminated due to exception: %s\n", ex.what()); | ||
123 | // } catch (...) { | ||
124 | // std::fprintf(stderr, "Terminated due to unknown exception\n"); | ||
125 | // } | ||
126 | // } else { | ||
127 | std::fprintf(stderr, "Terminated due to unknown reason.\n"); | ||
128 | // } | ||
129 | std::abort(); | ||
130 | } | ||
131 | |||
31 | class KubeImageProvider : public QQuickImageProvider | 132 | class KubeImageProvider : public QQuickImageProvider |
32 | { | 133 | { |
33 | public: | 134 | public: |
@@ -68,6 +169,11 @@ public: | |||
68 | 169 | ||
69 | int main(int argc, char *argv[]) | 170 | int main(int argc, char *argv[]) |
70 | { | 171 | { |
172 | |||
173 | std::signal(SIGSEGV, crashHandler); | ||
174 | std::signal(SIGABRT, crashHandler); | ||
175 | std::set_terminate(terminateHandler); | ||
176 | |||
71 | QApplication app(argc, argv); | 177 | QApplication app(argc, argv); |
72 | app.setFont(QFont{"Noto Sans", app.font().pointSize(), QFont::Normal}); | 178 | app.setFont(QFont{"Noto Sans", app.font().pointSize(), QFont::Normal}); |
73 | 179 | ||