From 6492654d213236b394b22c71dd77827aa100a2fb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jarkko=20P=C3=B6yry?= Date: Fri, 20 Mar 2015 15:29:47 -0700 Subject: [PATCH] Don't call exit() from signal handler. Bug: 19517387 Change-Id: I58d60a54a9473d14b60f981682307338e30ba087 --- framework/qphelper/qpCrashHandler.c | 17 ++++++++--------- framework/qphelper/qpCrashHandler.h | 4 ++++ framework/qphelper/qpDebugOut.c | 30 +++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/framework/qphelper/qpCrashHandler.c b/framework/qphelper/qpCrashHandler.c index 114ca97..f78c0c7 100644 --- a/framework/qphelper/qpCrashHandler.c +++ b/framework/qphelper/qpCrashHandler.c @@ -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 #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; diff --git a/framework/qphelper/qpCrashHandler.h b/framework/qphelper/qpCrashHandler.h index 9bb12e0..9f8ad71 100644 --- a/framework/qphelper/qpCrashHandler.h +++ b/framework/qphelper/qpCrashHandler.h @@ -25,6 +25,10 @@ #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); diff --git a/framework/qphelper/qpDebugOut.c b/framework/qphelper/qpDebugOut.c index e4a31f9..cb49ed8 100644 --- a/framework/qphelper/qpDebugOut.c +++ b/framework/qphelper/qpDebugOut.c @@ -23,6 +23,8 @@ #include "qpDebugOut.h" +#include "qpCrashHandler.h" /*!< for QP_USE_SIGNAL_HANDLER */ + #include #include @@ -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 +#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 -- 2.7.4