Don't call exit() from signal handler.
authorJarkko Pöyry <jpoyry@google.com>
Fri, 20 Mar 2015 22:29:47 +0000 (15:29 -0700)
committerJarkko Pöyry <jpoyry@google.com>
Sat, 21 Mar 2015 00:19:56 +0000 (17:19 -0700)
Bug: 19517387
Change-Id: I58d60a54a9473d14b60f981682307338e30ba087

framework/qphelper/qpCrashHandler.c
framework/qphelper/qpCrashHandler.h
framework/qphelper/qpDebugOut.c

index 114ca97..f78c0c7 100644 (file)
@@ -373,12 +373,11 @@ void qpCrashHandler_writeCrashInfo (qpCrashHandler* handler, qpWriteCrashInfoFun
 
 #else /* posix / generic implementation */
 
-#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS)
-#      define USE_SIGNAL_HANDLER 1
+#if defined(QP_USE_SIGNAL_HANDLER)
 #      include <signal.h>
 #endif
 
-#if defined(USE_SIGNAL_HANDLER)
+#if defined(QP_USE_SIGNAL_HANDLER)
 
 typedef struct SignalInfo_s
 {
@@ -397,7 +396,7 @@ static const SignalInfo s_signals[] =
        { SIGPIPE,              QP_CRASHTYPE_OTHER,                                     "SIGPIPE"       }
 };
 
-#endif /* USE_SIGNAL_HANDLER */
+#endif /* QP_USE_SIGNAL_HANDLER */
 
 struct qpCrashHandler_s
 {
@@ -407,7 +406,7 @@ struct qpCrashHandler_s
        qpCrashInfo                             crashInfo;
        int                                             crashSignal;
 
-#if defined(USE_SIGNAL_HANDLER)
+#if defined(QP_USE_SIGNAL_HANDLER)
        struct sigaction                oldHandlers[DE_LENGTH_OF_ARRAY(s_signals)];
 #endif
 };
@@ -424,7 +423,7 @@ static void assertFailureCallback (const char* expr, const char* file, int line)
                g_crashHandler->crashHandlerFunc(g_crashHandler, g_crashHandler->handlerUserPointer);
 }
 
-#if defined(USE_SIGNAL_HANDLER)
+#if defined(QP_USE_SIGNAL_HANDLER)
 
 static const SignalInfo* getSignalInfo (int sigNum)
 {
@@ -449,7 +448,7 @@ static void signalHandler (int sigNum)
                g_crashHandler->crashHandlerFunc(g_crashHandler, g_crashHandler->handlerUserPointer);
 }
 
-#endif /* USE_SIGNAL_HANDLER */
+#endif /* QP_USE_SIGNAL_HANDLER */
 
 qpCrashHandler* qpCrashHandler_create (qpCrashHandlerFunc handlerFunc, void* userPointer)
 {
@@ -471,7 +470,7 @@ qpCrashHandler* qpCrashHandler_create (qpCrashHandlerFunc handlerFunc, void* use
        /* DE_ASSERT callback. */
        deSetAssertFailureCallback(assertFailureCallback);
 
-#if defined(USE_SIGNAL_HANDLER)
+#if defined(QP_USE_SIGNAL_HANDLER)
        /* Register signal handlers. */
        {
                struct sigaction        action;
@@ -497,7 +496,7 @@ void qpCrashHandler_destroy (qpCrashHandler* handler)
 
        deSetAssertFailureCallback(DE_NULL);
 
-#if defined(USE_SIGNAL_HANDLER)
+#if defined(QP_USE_SIGNAL_HANDLER)
        /* Restore old handlers. */
        {
                int sigNdx;
index 9bb12e0..9f8ad71 100644 (file)
 
 #include "deDefs.h"
 
+#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS)
+#      define QP_USE_SIGNAL_HANDLER 1
+#endif
+
 typedef struct qpCrashHandler_s        qpCrashHandler;
 
 typedef void           (*qpCrashHandlerFunc)           (qpCrashHandler* crashHandler, void* userPtr);
index e4a31f9..cb49ed8 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "qpDebugOut.h"
 
+#include "qpCrashHandler.h" /*!< for QP_USE_SIGNAL_HANDLER */
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -157,23 +159,37 @@ static void exitProcess (void)
        TerminateProcess(curProc, -1);
 }
 
-#elif (DE_OS == DE_OS_IOS)
+#else
 
-#include "deThread.h"
+#if (DE_OS == DE_OS_IOS)
+#      include "deThread.h"    /*!< for deSleep() */
+#endif
+
+#if defined(QP_USE_SIGNAL_HANDLER)
+#      include <signal.h>
+#endif
 
 static void exitProcess (void)
 {
+#if (DE_OS == DE_OS_IOS)
        /* Since tests are in the same process as execserver, we want to give it
           a chance to stream complete log data before terminating. */
        deSleep(5000);
-       exit(-1);
-}
+#endif
 
-#else
+#if defined(QP_USE_SIGNAL_HANDLER)
+       /* QP_USE_SIGNAL_HANDLER defined, this means this function could have
+          been called from a signal handler. Calling exit() inside a signal
+          handler is not safe. */
 
-static void exitProcess (void)
-{
+       /* Flush all open FILES */
+       fflush(DE_NULL);
+
+       /* Kill without calling any _at_exit handlers as those might hang */
+       raise(SIGKILL);
+#else
        exit(-1);
+#endif
 }
 
 #endif