Add handlers for uncaught exceptions and new failures 04/123204/4
authorMu-Woong Lee <muwoong.lee@samsung.com>
Wed, 5 Apr 2017 02:19:40 +0000 (11:19 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Wed, 5 Apr 2017 04:25:20 +0000 (13:25 +0900)
Change-Id: I864ba0ddb05aaa8c1b21527a80a9f05cbf27861a
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
packaging/contextd.service
src/server/ServerMain.cpp
src/server/ServiceLoader.h

index cae5d7f813849e667f8db4dccde6f87b7137ad7b..2e2a9cde2e2a9e4b682c910a864e5aaadb2a3349 100644 (file)
@@ -9,7 +9,6 @@ Type=dbus
 BusName=org.tizen.context
 ExecStart=/usr/bin/contextd
 Restart=on-failure
-RestartSec=1
 
 [Install]
 WantedBy=multi-user.target
index 530d65cb1ab3382920f58cc9c2cf398c9a308c25..25134e9ef8a9d156ca22fa60b19ef6e8534f56e0 100644 (file)
  * limitations under the License.
  */
 
+#include <csignal>
 #include <cstdlib>
 #include <cstring>
+#include <unistd.h>
+#include <new>
+#include <exception>
+#include <stdexcept>
+
 #include <ContextTypes.h>
 #include "DBusConnector.h"
 #include "ServiceLoader.h"
 #include "ActiveUserMonitor.h"
 #include "AlarmInitializer.h"
 
+#define NEW_FAIL_LIMIT 3
+
 using namespace ctx;
 
 namespace {
@@ -40,7 +48,7 @@ GMainLoop* MainLoop::__mainLoop = NULL;
 bool MainLoop::start()
 {
        __mainLoop = g_main_loop_new(NULL, FALSE);
-       IF_FAIL_RETURN_TAG(__mainLoop, false, _E, "Memory allocation failed");
+       IF_FAIL_RETURN_TAG(__mainLoop, false, _E, E_STR_ALLOC);
 
        _I(CYAN("Starting..."));
        g_main_loop_run(__mainLoop);
@@ -106,7 +114,7 @@ static void __busLost(GDBusConnection* conn)
        __stopService(NULL);
 }
 
-static void __signalHandler(int signum)
+static void __onSignal(int signum)
 {
        _I(YELLOW("SIGNAL-%d: '%s'"), signum, strsignal(signum));
        static bool terminated = false;
@@ -116,17 +124,40 @@ static void __signalHandler(int signum)
        }
 }
 
+static void __onTerminate()
+{
+       try {
+               auto unknown = std::current_exception();
+               if (unknown) {
+                       std::rethrow_exception(unknown);
+               }
+       } catch (const std::exception& e) {
+               _E(RED("Unexpected exception: %s"), e.what());
+       } catch (...) {
+               _E(RED("Unknown exception"));
+       }
+}
+
+static void __onNewFailed()
+{
+       static unsigned failCount = 0;
+       _E_ALLOC;
+       failCount += 1;
+       if (failCount >= NEW_FAIL_LIMIT)
+               throw std::bad_alloc();
+       usleep(100000);
+}
+
 int main(int argc, char* argv[])
 {
-       static struct sigaction signalAction;
-       signalAction.sa_handler = __signalHandler;
-       sigemptyset(&signalAction.sa_mask);
-
-       sigaction(SIGINT, &signalAction, NULL);
-       sigaction(SIGHUP, &signalAction, NULL);
-       sigaction(SIGTERM, &signalAction, NULL);
-       sigaction(SIGQUIT, &signalAction, NULL);
-       sigaction(SIGABRT, &signalAction, NULL);
+       std::signal(SIGINT, __onSignal);
+       std::signal(SIGHUP, __onSignal);
+       std::signal(SIGTERM, __onSignal);
+       std::signal(SIGQUIT, __onSignal);
+       std::signal(SIGABRT, __onSignal);
+
+       std::set_terminate(__onTerminate);
+       std::set_new_handler(__onNewFailed);
 
        DBusConnector dbusConnector(__busAcquired, __busLost);
 
index 5bedbb2424051996f9995aba910b335da08d722f..7492f14a71dea37f699fe1557a35714d09daea7a 100644 (file)
@@ -45,8 +45,8 @@ namespace ctx {
                        ServiceBase *svc = NULL;
                        try {
                                svc = new ServiceType(conn);
-                       } catch (std::exception& e) {
-                               _W("Service creation failed (%s)", e.what());
+                       } catch (const std::runtime_error& e) {
+                               _I(YELLOW("%s"), e.what());
                                return;
                        }
                        if (svc->isUserService()) {