summaryrefslogtreecommitdiffstats
path: root/applications
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-09-02 13:41:26 -0600
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-09-06 12:28:19 +0200
commit323dae6c7fd982f444e1736410888037239e662c (patch)
treea063bdf5a987123ccfb629398f44c4631855b1ab /applications
parent2180926301a6417b8dd06dba9d65a337d3e91db1 (diff)
downloadkube-323dae6c7fd982f444e1736410888037239e662c.tar.gz
kube-323dae6c7fd982f444e1736410888037239e662c.zip
Install a crash handler
..that prints a backtrace on crash.
Diffstat (limited to 'applications')
-rw-r--r--applications/kube/CMakeLists.txt1
-rw-r--r--applications/kube/main.cpp106
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
26install(TARGETS ${PROJECT_NAME} DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) 27install(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
45void 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
83static int sCounter = 0;
84
85void 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
113void 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
31class KubeImageProvider : public QQuickImageProvider 132class KubeImageProvider : public QQuickImageProvider
32{ 133{
33public: 134public:
@@ -68,6 +169,11 @@ public:
68 169
69int main(int argc, char *argv[]) 170int 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