# HG changeset patch # User Santeri Piippo # Date 1400686743 -10800 # Node ID 0ed96169b8c093f74a51737199c3465b441dda0a # Parent b863b727c32197e85cb2328b85f5336338d22fb2 - crashcatcher: don't use the bomb box at all, instead just write the crashlog and then abort for good diff -r b863b727c321 -r 0ed96169b8c0 src/crashCatcher.cc --- a/src/crashCatcher.cc Wed May 21 18:15:09 2014 +0300 +++ b/src/crashCatcher.cc Wed May 21 18:39:03 2014 +0300 @@ -18,22 +18,18 @@ #ifdef __unix__ -#include #include #include -#include #include #include +#include "crashCatcher.h" +#include "basics.h" +#include "dialogs.h" #ifdef Q_OS_LINUX # include #endif -#include "crashCatcher.h" -#include "basics.h" -#include "dialogs.h" -#include "mainWindow.h" - // Is the crash catcher active now? static bool g_crashCatcherActive = false; @@ -48,21 +44,30 @@ SIGILL, // illegal instructions }); +// +// Removes the signal handler from SIGABRT and then aborts. +// +static void finalAbort() +{ + struct sigaction sighandler; + sighandler.sa_handler = SIG_DFL; + sighandler.sa_flags = 0; + sigaction (SIGABRT, &sighandler, 0); + abort(); +} + // ============================================================================= // static void handleCrash (int sig) { - printf ("%s: crashed with signal %d, launching gdb\n", __func__, sig); + printf ("!! Caught signal %d, launching gdb\n", sig); if (g_crashCatcherActive) { - printf ("caught signal while crash catcher is active!\n"); - exit (149); + printf ("Caught signal while crash catcher is active! Execution cannot continue.\n"); + finalAbort(); } - if (g_win != null) - g_win->hide(); - const pid_t pid = getpid(); QProcess proc; QTemporaryFile commandsFile; @@ -75,13 +80,10 @@ commandsFile.write (String ("backtrace full\n").toLocal8Bit()); commandsFile.write (String ("detach\n").toLocal8Bit()); commandsFile.write (String ("quit").toLocal8Bit()); - commandsFile.flush(); commandsFile.close(); } - QStringList args ({"-x", commandsFile.fileName()}); - - proc.start ("gdb", args); + proc.start ("gdb", {"-x", commandsFile.fileName()}); // Linux doesn't allow ptrace to be used on anything but direct child processes // so we need to use prctl to register an exception to this to allow GDB attach to us. @@ -93,7 +95,7 @@ proc.waitForFinished (1000); String output = String (proc.readAllStandardOutput()); String err = String (proc.readAllStandardError()); - QFile f ("ldforge-crash.log"); + QFile f (UNIXNAME "-crash.log"); if (f.open (QIODevice::WriteOnly)) { @@ -104,14 +106,21 @@ f.close(); } - bombBox (format ("

Program crashed with signal %1

\n\n" - "%2" - "

GDB stdout:

%3
\n" - "

GDB stderr:

%4
", - sig, g_assertionFailure, output, err)); + if (g_assertionFailure.isEmpty()) + { + printf ("Crashlog written to " UNIXNAME "-crash.log. Aborting.\n"); + } + else + { + printf ("Assertion failed: \"%s\". Backtrace written to " UNIXNAME "-crash.log.\n", + qPrintable (g_assertionFailure)); + } + + finalAbort(); } -// ============================================================================= +// +// Initializes the crash catcher. // void initCrashCatcher() { @@ -121,10 +130,17 @@ sigemptyset (&sighandler.sa_mask); for (int sig : g_signalsToCatch) - sigaction (sig, &sighandler, null); + { + if (sigaction (sig, &sighandler, null) == -1) + { + fprint (stderr, "Couldn't set signal handler %1: %2", sig, strerror (errno)); + g_signalsToCatch.removeOne (sig); + } + } - print ("%1: crash catcher hooked to signals: %2\n", __func__, g_signalsToCatch); + print ("Crash catcher hooked to signals: %1\n", g_signalsToCatch); } + #endif // #ifdef __unix__ // =============================================================================