--- qsampler/trunk/src/main.cpp 2010/03/12 16:02:32 2064 +++ qsampler/trunk/src/main.cpp 2010/03/13 12:44:15 2065 @@ -235,13 +235,77 @@ //------------------------------------------------------------------------- +// stacktrace - Signal crash handler. +// + +#ifdef CONFIG_STACKTRACE +#if defined(__GNUC__) && defined(Q_OS_LINUX) + +#include +#include +#include +#include + +void stacktrace ( int signo ) +{ + pid_t pid; + int rc; + int status = 0; + char cmd[80]; + + // Reinstall default handler; prevent race conditions... + signal(signo, SIG_DFL); + + static const char *shell = "/bin/sh"; + static const char *format = "gdb -q --batch --pid=%d --eval-command=bt"; + + snprintf(cmd, sizeof(cmd), format, (int) getpid()); + + pid = fork(); + + // Fork failure! + if (pid < 0) + return; + + // Fork child... + if (pid == 0) { + execl(shell, shell, "-c", cmd, NULL); + _exit(1); + return; + } + + // Parent here: wait for child to terminate... + do { rc = waitpid(pid, &status, 0); } + while ((rc < 0) && (errno == EINTR)); + + // Dispatch any logging, if any... + QApplication::processEvents(QEventLoop::AllEvents, 3000); + + // Make sure everyone terminates... + kill(pid, SIGTERM); + _exit(1); +} + +#endif +#endif + + +//------------------------------------------------------------------------- // main - The main program trunk. // int main ( int argc, char **argv ) { Q_INIT_RESOURCE(qsampler); - +#ifdef CONFIG_STACKTRACE +#if defined(__GNUC__) && defined(Q_OS_LINUX) + signal(SIGILL, stacktrace); + signal(SIGFPE, stacktrace); + signal(SIGSEGV, stacktrace); + signal(SIGABRT, stacktrace); + signal(SIGBUS, stacktrace); +#endif +#endif qsamplerApplication app(argc, argv); #if defined(__APPLE__) // Toshi Nagata 20080105