summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Weimer <bernd.weimer@pelagicore.com>2020-03-04 17:30:38 +0100
committerBernd Weimer <bernd.weimer@pelagicore.com>2020-03-09 15:43:41 +0100
commitf43d30ffba0ed8d11b3819d2fad63e6bf1cf34b8 (patch)
tree6d2fdc7801560f71b27767530566719a95d9563b
parent01c54e360ee0dd3575193b8d2aaf4581f8918dbd (diff)
downloadqtapplicationmanager-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.cpp13
-rw-r--r--src/common-lib/unixsignalhandler.cpp37
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;