diff options
author | Bernd Weimer <bernd.weimer@pelagicore.com> | 2020-03-04 17:30:38 +0100 |
---|---|---|
committer | Bernd Weimer <bernd.weimer@pelagicore.com> | 2020-03-09 15:43:41 +0100 |
commit | f43d30ffba0ed8d11b3819d2fad63e6bf1cf34b8 (patch) | |
tree | 6d2fdc7801560f71b27767530566719a95d9563b | |
parent | 01c54e360ee0dd3575193b8d2aaf4581f8918dbd (diff) | |
download | qtapplicationmanager-f43d30ffba0ed8d11b3819d2fad63e6bf1cf34b8.tar.gz |
Improve crash handler
- Added two other signals, that generate a core dump by default to
the crash handler: SIGQUIT and SIGSYS.
- Sending SIGABORT to processes in the same group would generate a
core dump of another process - using SIGTERM now.
- Setup alternate signal stack only once and hence allocate the
memory only once (there can be only one alternate signal stack)
Change-Id: I861505668dc2484730ec79410612f55698b695c4
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
-rw-r--r-- | src/common-lib/crashhandler.cpp | 13 | ||||
-rw-r--r-- | src/common-lib/unixsignalhandler.cpp | 37 |
2 files changed, 27 insertions, 23 deletions
diff --git a/src/common-lib/crashhandler.cpp b/src/common-lib/crashhandler.cpp index 22683612..9b2db648 100644 --- a/src/common-lib/crashhandler.cpp +++ b/src/common-lib/crashhandler.cpp @@ -326,7 +326,7 @@ static void initBacktraceUnix() # endif UnixSignalHandler::instance()->install(UnixSignalHandler::RawSignalHandler, - { SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT }, + { SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT, SIGQUIT, SIGSYS }, [](int sig) { UnixSignalHandler::instance()->resetToDefault(sig); char buffer[256]; @@ -387,6 +387,7 @@ static void logCrashInfo(LogToDestination logTo, const char *why, int stackFrame #if defined(Q_OS_LINUX) long tid = syscall(SYS_gettid); bool isMainThread = (tid == pid); + #else long tid = -1; bool isMainThread = pthread_main_np(); @@ -540,7 +541,8 @@ static void crashHandler(const char *why, int stackFramesToIgnore) // 1) avoid recursions // 2) SIGABRT to re-enable standard abort() handling // 3) SIGINT, so that you can Ctrl+C the app if the crash handler ends up freezing - UnixSignalHandler::instance()->resetToDefault({ SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT, SIGINT }); + UnixSignalHandler::instance()->resetToDefault({ SIGFPE, SIGSEGV, SIGILL, SIGBUS, + SIGPIPE, SIGABRT, SIGINT, SIGQUIT, SIGSYS }); logCrashInfo(Console, why, stackFramesToIgnore); @@ -573,11 +575,12 @@ static void crashHandler(const char *why, int stackFramesToIgnore) logCrashInfo(Dlt, why, stackFramesToIgnore); # endif - // make sure to kill our sub-process as well - kill(0, SIGABRT); + // make sure to terminate our sub-process as well, but not ourselves + signal(SIGTERM, SIG_IGN); + kill(0, SIGTERM); if (dumpCore) { - logMsg(Console, "\n > the process will be aborted (core dumped)\n\n"); + logMsg(Console, "\n > the process will be aborted (core dumped)\n"); abort(); } diff --git a/src/common-lib/unixsignalhandler.cpp b/src/common-lib/unixsignalhandler.cpp index cd51fae3..c208412b 100644 --- a/src/common-lib/unixsignalhandler.cpp +++ b/src/common-lib/unixsignalhandler.cpp @@ -56,15 +56,6 @@ QT_BEGIN_NAMESPACE_AM -#if defined(Q_OS_UNIX) - -// make it clear in the valgrind backtrace that this is a deliberate leak -static void *malloc_valgrind_ignore(size_t size) -{ - return malloc(size); -} -#endif - // sigmask() is not available on Windows UnixSignalHandler::am_sigmask_t UnixSignalHandler::am_sigmask(int sig) { @@ -73,12 +64,29 @@ UnixSignalHandler::am_sigmask_t UnixSignalHandler::am_sigmask(int sig) UnixSignalHandler *UnixSignalHandler::s_instance = nullptr; +#if defined(Q_OS_UNIX) +// make it clear in the valgrind backtrace that this is a deliberate leak +static void *malloc_valgrind_ignore(size_t size) +{ + return malloc(size); +} + UnixSignalHandler::UnixSignalHandler() : QObject() -#if defined(Q_OS_UNIX) , m_pipe { -1, -1 } -#endif +{ + // Setup alternate signal stack (to get backtrace for stack overflow) + stack_t sigstack; + // valgrind will report this as leaked: nothing we can do about it + sigstack.ss_sp = malloc_valgrind_ignore(SIGSTKSZ); + sigstack.ss_size = SIGSTKSZ; + sigstack.ss_flags = 0; + sigaltstack(&sigstack, nullptr); +} +#else +UnixSignalHandler::UnixSignalHandler() : QObject() { } +#endif UnixSignalHandler *UnixSignalHandler::instance() { @@ -208,13 +216,6 @@ bool UnixSignalHandler::install(Type handlerType, const std::initializer_list<in m_handlers.emplace_back(sig, handlerType == ForwardedToEventLoopHandler, handler); #if defined(Q_OS_UNIX) - // Use alternate signal stack to get backtrace for stack overflow - stack_t sigstack; - sigstack.ss_sp = malloc_valgrind_ignore(SIGSTKSZ); // valgrind will report this as leaked: nothing we can do about it - sigstack.ss_size = SIGSTKSZ; - sigstack.ss_flags = 0; - sigaltstack(&sigstack, nullptr); - struct sigaction sigact; sigact.sa_flags = SA_ONSTACK; sigact.sa_handler = sigHandler; |