44 }); |
44 }); |
45 |
45 |
46 // ============================================================================= |
46 // ============================================================================= |
47 // ----------------------------------------------------------------------------- |
47 // ----------------------------------------------------------------------------- |
48 static void handleCrash (int sig) |
48 static void handleCrash (int sig) |
49 { printf ("%s: crashed with signal %d, launching gdb\n", __func__, sig); |
49 { |
|
50 printf ("%s: crashed with signal %d, launching gdb\n", __func__, sig); |
50 |
51 |
51 if (g_crashCatcherActive) |
52 if (g_crashCatcherActive) |
52 { printf ("caught signal while crash catcher is active!\n"); |
53 { |
|
54 printf ("caught signal while crash catcher is active!\n"); |
53 exit (149); |
55 exit (149); |
54 } |
56 } |
55 |
57 |
56 const pid_t pid = getpid(); |
58 const pid_t pid = getpid(); |
57 QProcess proc; |
59 QProcess proc; |
58 QTemporaryFile commandsFile; |
60 QTemporaryFile commandsFile; |
59 |
61 |
60 g_crashCatcherActive = true; |
62 g_crashCatcherActive = true; |
61 |
63 |
62 if (commandsFile.open()) |
64 if (commandsFile.open()) |
63 { commandsFile.write (fmt ("attach %1\n", pid).toLocal8Bit()); |
65 { |
|
66 commandsFile.write (fmt ("attach %1\n", pid).toLocal8Bit()); |
64 commandsFile.write (str ("backtrace full\n").toLocal8Bit()); |
67 commandsFile.write (str ("backtrace full\n").toLocal8Bit()); |
65 commandsFile.write (str ("detach\n").toLocal8Bit()); |
68 commandsFile.write (str ("detach\n").toLocal8Bit()); |
66 commandsFile.write (str ("quit").toLocal8Bit()); |
69 commandsFile.write (str ("quit").toLocal8Bit()); |
67 commandsFile.flush(); |
70 commandsFile.flush(); |
68 commandsFile.close(); |
71 commandsFile.close(); |
89 } |
92 } |
90 |
93 |
91 // ============================================================================= |
94 // ============================================================================= |
92 // ----------------------------------------------------------------------------- |
95 // ----------------------------------------------------------------------------- |
93 void initCrashCatcher() |
96 void initCrashCatcher() |
94 { struct sigaction sighandler; |
97 { |
|
98 struct sigaction sighandler; |
95 sighandler.sa_handler = &handleCrash; |
99 sighandler.sa_handler = &handleCrash; |
96 sighandler.sa_flags = 0; |
100 sighandler.sa_flags = 0; |
97 sigemptyset (&sighandler.sa_mask); |
101 sigemptyset (&sighandler.sa_mask); |
98 |
102 |
99 for (int sig : g_signalsToCatch) |
103 for (int sig : g_signalsToCatch) |
108 // the bomb box straight in Windows while in Linux we let abort() trigger the |
112 // the bomb box straight in Windows while in Linux we let abort() trigger the |
109 // signal handler, which will cause the usual bomb box with GDB diagnostics. |
113 // signal handler, which will cause the usual bomb box with GDB diagnostics. |
110 // Said prompt will embed the assertion failure information. |
114 // Said prompt will embed the assertion failure information. |
111 // ----------------------------------------------------------------------------- |
115 // ----------------------------------------------------------------------------- |
112 void assertionFailure (const char* file, int line, const char* funcname, const char* expr) |
116 void assertionFailure (const char* file, int line, const char* funcname, const char* expr) |
113 { str errmsg = fmt ( |
117 { |
|
118 str errmsg = fmt ( |
114 "<p><b>File</b>: <tt>%1</tt><br />" |
119 "<p><b>File</b>: <tt>%1</tt><br />" |
115 "<b>Line</b>: <tt>%2</tt><br />" |
120 "<b>Line</b>: <tt>%2</tt><br />" |
116 "<b>Function:</b> <tt>%3</tt></p>" |
121 "<b>Function:</b> <tt>%3</tt></p>" |
117 "<p>Assertion <b><tt>`%4'</tt></b> failed.</p>", |
122 "<p>Assertion <b><tt>`%4'</tt></b> failed.</p>", |
118 file, line, funcname, expr); |
123 file, line, funcname, expr); |