Fri, 18 Nov 2016 02:56:53 +0200
Cleaned up crash catcher, fixed missing <math.h> include
src/basics.h | file | annotate | diff | comparison | revisions | |
src/crashCatcher.cpp | file | annotate | diff | comparison | revisions | |
src/crashCatcher.h | file | annotate | diff | comparison | revisions | |
src/format.h | file | annotate | diff | comparison | revisions | |
src/main.cpp | file | annotate | diff | comparison | revisions | |
tools/linelength.py | file | annotate | diff | comparison | revisions |
--- a/src/basics.h Thu Nov 17 14:12:59 2016 +0200 +++ b/src/basics.h Fri Nov 18 02:56:53 2016 +0200 @@ -23,6 +23,7 @@ #include <QMetaType> #include <QVector3D> #include <functional> +#include <math.h> #include "macros.h" #include "transform.h" #include "types/matrix.h"
--- a/src/crashCatcher.cpp Thu Nov 17 14:12:59 2016 +0200 +++ b/src/crashCatcher.cpp Fri Nov 18 02:56:53 2016 +0200 @@ -21,8 +21,8 @@ #ifdef Q_OS_UNIX # include <QProcess> # include <QTemporaryFile> +# include <signal.h> # include <unistd.h> -# include <signal.h> # include "crashCatcher.h" # include "dialogs.h" @@ -30,74 +30,92 @@ # include <sys/prctl.h> # endif - -// Removes the signal handler from SIGABRT and then aborts. +/* + * finalAbort + * + * Removes the signal handler from SIGABRT and then aborts. + * This really aborts instead of falling back into the crash handler. + */ +// static void finalAbort() { struct sigaction sighandler; sighandler.sa_handler = SIG_DFL; sighandler.sa_flags = 0; - sigaction (SIGABRT, &sighandler, 0); + sigaction(SIGABRT, &sighandler, 0); abort(); } - -static void handleCrash (int sig) +/* + * handleCrash + * + * Handles a crash signal. Launches gdb and gets debug info for a post-mortem. + */ +static void handleCrash(int signal) { static bool isActive = false; - printf ("!! Caught signal %d, launching gdb\n", sig); + printf("!! Caught signal %d, launching gdb\n", signal); if (isActive) { - printf ("Caught signal while crash catcher is active! Execution cannot continue.\n"); + printf("Caught signal while crash catcher is active! Execution cannot continue.\n"); finalAbort(); } - pid_t const pid (getpid()); - QProcess proc; QTemporaryFile commandsFile; isActive = true; if (commandsFile.open()) { - commandsFile.write (format ("attach %1\n", pid).toLocal8Bit()); - commandsFile.write (QString ("backtrace full\n").toLocal8Bit()); - commandsFile.write (QString ("detach\n").toLocal8Bit()); - commandsFile.write (QString ("quit").toLocal8Bit()); + commandsFile.write(format("attach %1\n", getpid()).toLocal8Bit()); + commandsFile.write("backtrace full\n"); + commandsFile.write("detach\n"); + commandsFile.write("quit"); commandsFile.close(); + + QProcess process; + process.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. +#ifdef Q_OS_LINUX + prctl(PR_SET_PTRACER, process.pid(), 0, 0, 0); +#endif + + process.waitForFinished(1000); + QString output = process.readAllStandardOutput(); + QString errorOutput = process.readAllStandardError(); + QFile file {UNIXNAME "-crash.log"}; + + if (file.open(QIODevice::WriteOnly)) + { + fprint(file, format("=== Program crashed with signal %1 ===\n\n" + "GDB stdout:\n%3\nGDB stderr:\n%4\n", signal, output, errorOutput)); + file.close(); + printf("Backtrace written to " UNIXNAME "-crash.log. Aborting.\n"); + } + else + { + printf("Unable to write a crashlog.\n"); + } + } + else + { + printf("Unable to write commands to temporary file."); } - 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. - // We need to do this now and no earlier because only now we actually know GDB's PID. -#ifdef Q_OS_LINUX - prctl (PR_SET_PTRACER, proc.pid(), 0, 0, 0); -#endif - - proc.waitForFinished (1000); - QString output (proc.readAllStandardOutput()); - QString err (proc.readAllStandardError()); - QFile f (UNIXNAME "-crash.log"); - - if (f.open (QIODevice::WriteOnly)) - { - fprint (f, format ("=== Program crashed with signal %1 ===\n\n" - "GDB stdout:\n%3\nGDB stderr:\n%4\n", sig, - output, err)); - f.close(); - } - - printf ("Backtrace written to " UNIXNAME "-crash.log. Aborting.\n"); finalAbort(); } - -void initCrashCatcher() +/* + * initializeCrashHandler + * + * Creates handlers for crash signals, so that we can create backtraces for them. + */ +void initializeCrashHandler() { // List of signals to catch and crash on - static const int signalsToCatch[] = { + QVector<int> signalsToCatch = { SIGSEGV, // segmentation fault SIGABRT, // abort() calls SIGFPE, // floating point exceptions (e.g. division by zero) @@ -109,13 +127,13 @@ sighandler.sa_flags = 0; sigemptyset (&sighandler.sa_mask); - for (int sig : signalsToCatch) + for (int signal : signalsToCatch) { - if (sigaction (sig, &sighandler, nullptr) == -1) - fprint (stderr, "Couldn't set signal handler %1: %2", sig, strerror (errno)); + if (sigaction(signal, &sighandler, nullptr) == -1) + fprint(stderr, "Couldn't set signal handler %1: %2", signal, strerror(errno)); } - print ("Crash catcher hooked to signals: %1\n", signalsToCatch); + print("Crash catcher hooked to signals: %1\n", signalsToCatch); } -#endif // Q_OS_UNIX \ No newline at end of file +#endif // Q_OS_UNIX
--- a/src/crashCatcher.h Thu Nov 17 14:12:59 2016 +0200 +++ b/src/crashCatcher.h Fri Nov 18 02:56:53 2016 +0200 @@ -20,7 +20,7 @@ #include "main.h" #ifdef Q_OS_UNIX -void initCrashCatcher(); +void initializeCrashHandler(); #else -void initCrashCatcher() {} +void initializeCrashHandler() {} #endif
--- a/src/format.h Thu Nov 17 14:12:59 2016 +0200 +++ b/src/format.h Fri Nov 18 02:56:53 2016 +0200 @@ -46,7 +46,7 @@ } template<typename T> - StringFormatArg (const QList<T>& a) + StringFormatArg (const QVector<T>& a) { m_text = "{";
--- a/src/main.cpp Thu Nov 17 14:12:59 2016 +0200 +++ b/src/main.cpp Fri Nov 18 02:56:53 2016 +0200 @@ -43,7 +43,7 @@ paths->checkPaths(); paths->deleteLater(); - initCrashCatcher(); + initializeCrashHandler(); initColors(); MainWindow* win = new MainWindow(configObject); win->show();
--- a/tools/linelength.py Thu Nov 17 14:12:59 2016 +0200 +++ b/tools/linelength.py Fri Nov 18 02:56:53 2016 +0200 @@ -5,7 +5,7 @@ for filename in argv[1:]: with open(filename, 'r') as fp: try: - exceeders = [(i + 1) for i, ln in enumerate(fp.read().splitlines()) if len(ln.replace('\t', ' ')) > 120] + exceeders = [(i + 1) for i, ln in enumerate(fp.read().splitlines()) if len(ln.replace('\t', ' ')) > 140] for linenumber in exceeders: stderr.write('%s:%d: warning: line length exceeds 120 characters\n' % (realpath(filename), linenumber))