summaryrefslogtreecommitdiffstats
path: root/synchronizer
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-22 13:12:02 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-22 13:12:02 +0200
commitecf5bd3c4fd8557b06c6849b317d8d3ccaca528f (patch)
tree6d7d038b6d705356040e8b1f331c075f90b7c690 /synchronizer
parent6864e4accaafa4fa90332719bff5a85a0e92b242 (diff)
downloadsink-ecf5bd3c4fd8557b06c6849b317d8d3ccaca528f.tar.gz
sink-ecf5bd3c4fd8557b06c6849b317d8d3ccaca528f.zip
A better crashhandler that notifies the client of the crash.
Diffstat (limited to 'synchronizer')
-rw-r--r--synchronizer/main.cpp70
1 files changed, 64 insertions, 6 deletions
diff --git a/synchronizer/main.cpp b/synchronizer/main.cpp
index 179fbf5..e000e03 100644
--- a/synchronizer/main.cpp
+++ b/synchronizer/main.cpp
@@ -22,6 +22,9 @@
22 22
23#include <signal.h> 23#include <signal.h>
24#include <execinfo.h> 24#include <execinfo.h>
25#include <csignal>
26#include <iostream>
27#include <cstdlib>
25 28
26#include "listener.h" 29#include "listener.h"
27#include "log.h" 30#include "log.h"
@@ -29,10 +32,10 @@
29#undef DEBUG_AREA 32#undef DEBUG_AREA
30#define DEBUG_AREA "resource" 33#define DEBUG_AREA "resource"
31 34
32void crashHandler(int sig) 35Listener *listener = nullptr;
33{
34 std::fprintf(stderr, "Error: signal %d\n", sig);
35 36
37void printStacktrace()
38{
36 QString s; 39 QString s;
37 void *trace[256]; 40 void *trace[256];
38 int n = backtrace(trace, 256); 41 int n = backtrace(trace, 256);
@@ -51,18 +54,73 @@ void crashHandler(int sig)
51 free(strings); 54 free(strings);
52 } 55 }
53 } 56 }
57}
58
59int sCounter = 0;
60
61void crashHandler(int signal)
62{
63 //Guard against crashing in here
64 if (sCounter > 1) {
65 std::_Exit(EXIT_FAILURE);
66 return;
67 }
68 sCounter++;
69
70 if (signal == SIGABRT) {
71 std::cerr << "SIGABRT received\n";
72 } else if (signal == SIGSEGV) {
73 std::cerr << "SIGSEV received\n";
74 } else {
75 std::cerr << "Unexpected signal " << signal << " received\n";
76 }
77
78 printStacktrace();
79
80 //Get the word out that we're going down
81 listener->emergencyAbortAllConnections();
54 82
55 std::system("exec gdb -p \"$PPID\" -ex \"thread apply all bt\""); 83 // std::system("exec gdb -p \"$PPID\" -ex \"thread apply all bt\"");
56 // This only works if we actually have xterm and X11 available 84 // This only works if we actually have xterm and X11 available
57 // std::system("exec xterm -e gdb -p \"$PPID\""); 85 // std::system("exec xterm -e gdb -p \"$PPID\"");
58 86
87 std::_Exit(EXIT_FAILURE);
88 return;
89}
90
91void terminateHandler()
92{
93 std::exception_ptr exptr = std::current_exception();
94 if (exptr != 0)
95 {
96 // the only useful feature of std::exception_ptr is that it can be rethrown...
97 try
98 {
99 std::rethrow_exception(exptr);
100 }
101 catch (std::exception &ex)
102 {
103 std::fprintf(stderr, "Terminated due to exception: %s\n", ex.what());
104 }
105 catch (...)
106 {
107 std::fprintf(stderr, "Terminated due to unknown exception\n");
108 }
109 }
110 else
111 {
112 std::fprintf(stderr, "Terminated due to unknown reason :(\n");
113 }
59 std::abort(); 114 std::abort();
60} 115}
61 116
62int main(int argc, char *argv[]) 117int main(int argc, char *argv[])
63{ 118{
64 // For crashes 119 // For crashes
65 signal(SIGSEGV, crashHandler); 120 std::signal(SIGSEGV, crashHandler);
121 std::signal(SIGABRT, crashHandler);
122 std::set_terminate(terminateHandler);
123
66 QCoreApplication app(argc, argv); 124 QCoreApplication app(argc, argv);
67 125
68 if (argc < 3) { 126 if (argc < 3) {
@@ -81,7 +139,7 @@ int main(int argc, char *argv[])
81 return -1; 139 return -1;
82 } 140 }
83 141
84 Listener *listener = new Listener(instanceIdentifier, resourceType, &app); 142 listener = new Listener(instanceIdentifier, resourceType, &app);
85 143
86 QObject::connect(&app, &QCoreApplication::aboutToQuit, listener, &Listener::closeAllConnections); 144 QObject::connect(&app, &QCoreApplication::aboutToQuit, listener, &Listener::closeAllConnections);
87 QObject::connect(listener, &Listener::noClients, &app, &QCoreApplication::quit); 145 QObject::connect(listener, &Listener::noClients, &app, &QCoreApplication::quit);