[Prevent] Handle unhandled exceptions in wrt-launcher.
authorJan Olszak <j.olszak@samsung.com>
Wed, 12 Dec 2012 10:02:45 +0000 (11:02 +0100)
committerGerrit Code Review <gerrit2@kim11>
Wed, 12 Dec 2012 11:19:55 +0000 (20:19 +0900)
[Issue#] Unhandled exceptions propagate to main().
[Bug] N/A
[Cause] N/A
[Solution] Catch all exceptions and log them.
[Verification] Build wrt.

Change-Id: I7e8f81dd2478154c303d3d02fb8f4d56b0fc6efd

src/wrt-launcher/wrt-launcher.cpp

index fc8783e..0f37e0e 100644 (file)
@@ -31,6 +31,7 @@
 #include <dpl/wrt-dao-ro/wrt_db_types.h>
 #include <dpl/wrt-dao-rw/global_dao.h>
 #include <dpl/wrt-dao-ro/global_dao_read_only.h>
+#include <dpl/exception.h>
 
 #define TIMEOUT_DEFAULT     10
 #define ROOT_DEFAULT_UID 0
@@ -191,301 +192,305 @@ static void sighandler(int signo, siginfo_t *si, void *data);
 
 int main(int argc, char* argv[])
 {
-    int next_opt, opt_idx = 0;
-    int timeout = TIMEOUT_DEFAULT;
-    char pkgname[256] = "";
-    char temp_arg[256] = "";
-    char pid[6] = "";
-    char op = '\0';
-    bool isDebugMode = false;
-    struct sigaction sigact;
-
-    service_h serviceHandle = NULL;
-    int ret = SERVICE_ERROR_NONE;
-
-    program = argv[0];
-
-    static struct option long_options[] = {
-        {"help", no_argument, 0, 'h'},
-        {"list", no_argument, 0, 'l'},
-        {"start", required_argument, 0, 's'},
-        {"kill", required_argument, 0, 'k'},
-        {"debug", no_argument, 0, 'd'},
-        {"timeout", required_argument, 0, 't'},
-        {"developer-mode", required_argument, 0, 'v'},
-        {"compliance-mode", required_argument, 0, 'c'},
-        {"fake-imei", required_argument, 0, 'i'},
-        {"fake-meid", required_argument, 0, 'm'},
-        {0, 0, 0, 0}
-    };
-
-    if (argv[1] == NULL) {
-        /* exit if any argument doesn't exist */
-        print_help(stdout, 0);
-        return -1;
-    }
-
-    if (ROOT_DEFAULT_UID == geteuid()) {
-        if (RETURN_ERROR == setuid(ROOT_DEFAULT_UID)) {
-            perror("Fail to set uid");
-        }
-    }
-    if (ROOT_DEFAULT_GID == getegid()) {
-        if (RETURN_ERROR == setgid(ROOT_DEFAULT_GID)) {
-            perror("Fail to set gid");
-        }
-    }
-
-    do {
-        next_opt = getopt_long(argc,
-                               argv,
-                               "hls:k:dt:v:c:i:m:",
-                               long_options,
-                               &opt_idx);
-
-        switch (next_opt) {
-        case 'h':
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        int next_opt, opt_idx = 0;
+        int timeout = TIMEOUT_DEFAULT;
+        char pkgname[256] = "";
+        char temp_arg[256] = "";
+        char pid[6] = "";
+        char op = '\0';
+        bool isDebugMode = false;
+        struct sigaction sigact;
+
+        service_h serviceHandle = NULL;
+        int ret = SERVICE_ERROR_NONE;
+
+        program = argv[0];
+
+        static struct option long_options[] = {
+            {"help", no_argument, 0, 'h'},
+            {"list", no_argument, 0, 'l'},
+            {"start", required_argument, 0, 's'},
+            {"kill", required_argument, 0, 'k'},
+            {"debug", no_argument, 0, 'd'},
+            {"timeout", required_argument, 0, 't'},
+            {"developer-mode", required_argument, 0, 'v'},
+            {"compliance-mode", required_argument, 0, 'c'},
+            {"fake-imei", required_argument, 0, 'i'},
+            {"fake-meid", required_argument, 0, 'm'},
+            {0, 0, 0, 0}
+        };
+
+        if (argv[1] == NULL) {
+            /* exit if any argument doesn't exist */
             print_help(stdout, 0);
-            break;
+            return -1;
+        }
 
-        case 'l':
-            if (!display_widget_info()) {
-                printf("Fail to display the list of installed widgets");
-                return -1;
-            }
-            break;
-
-        case 's':
-        case 'k':
-            strncpy(temp_arg, optarg, strlen(optarg));
-            op = next_opt;
-            break;
-
-        case 't':
-            timeout = atoi(optarg);
-            if (timeout < 0 ) {
-                timeout = TIMEOUT_DEFAULT;
+        if (ROOT_DEFAULT_UID == geteuid()) {
+            if (RETURN_ERROR == setuid(ROOT_DEFAULT_UID)) {
+                perror("Fail to set uid");
             }
-            break;
-
-        case 'd':
-            // create service
-            ret = service_create(&serviceHandle);
-            if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
-                LogError("Fail to create service");
-                return FALSE;
+        }
+        if (ROOT_DEFAULT_GID == getegid()) {
+            if (RETURN_ERROR == setgid(ROOT_DEFAULT_GID)) {
+                perror("Fail to set gid");
             }
+        }
 
-            // set debug mode
-            ret = service_add_extra_data(serviceHandle,
-                                         "debug",
-                                         "true");
-            if (SERVICE_ERROR_NONE != ret) {
-                LogError("Fail to set debug mode [" << ret << "]");
-                service_destroy(serviceHandle);
-                return FALSE;
-            }
+        do {
+            next_opt = getopt_long(argc,
+                                   argv,
+                                   "hls:k:dt:v:c:i:m:",
+                                   long_options,
+                                   &opt_idx);
 
-            // set pid
-            snprintf(pid, sizeof(pid), "%d", getpid());
-            ret = service_add_extra_data(serviceHandle,
-                                         "pid",
-                                         pid);
-            if (SERVICE_ERROR_NONE != ret) {
-                LogError("Fail to set pid [" << ret << "]");
-                service_destroy(serviceHandle);
-                return FALSE;
-            }
-            isDebugMode = true;
-            break;
-
-        case 'v':
-            strncpy(temp_arg, optarg, strlen(optarg));
-            if(!attachDbConnection()) return FALSE;
-            if (!strcmp("1", temp_arg)) {
-                WrtDB::GlobalDAO::SetDeveloperMode(true);
-            } else {
-                WrtDB::GlobalDAO::SetDeveloperMode(false);
-            }
-            break;
-        case 'c':
-            strncpy(temp_arg, optarg, strlen(optarg));
-            if(!attachDbConnection()) return FALSE;
-            if(!strcmp("1", temp_arg)) {
-                WrtDB::GlobalDAO::setComplianceMode(true);
-            } else {
-                WrtDB::GlobalDAO::setComplianceMode(false);
-            }
-            break;
-        case 'i':
-            strncpy(temp_arg, optarg, strlen(optarg));
-            if(!attachDbConnection()) return FALSE;
-            WrtDB::GlobalDAO::setComplianceFakeImei(temp_arg);
-            break;
-        case 'm':
-            strncpy(temp_arg, optarg, strlen(optarg));
-            if(!attachDbConnection()) return FALSE;
-            WrtDB::GlobalDAO::setComplianceFakeMeid(temp_arg);
-            break;
-
-        case -1:
-            break;
-
-        default:
-            print_help(stdout, 0);
-            break;
-        }
-    } while (next_opt != -1);
+            switch (next_opt) {
+            case 'h':
+                print_help(stdout, 0);
+                break;
 
-    if ((op == 's') || (op == 'k')) {
-        std::string temp;
+            case 'l':
+                if (!display_widget_info()) {
+                    printf("Fail to display the list of installed widgets");
+                    return -1;
+                }
+                break;
 
-        if (NULL == g_dbConnection.get()) {
-            Try {
-                g_dbConnection.reset(new DBConnection());
-                g_dbConnection->AttachDatabase();
-            }
-            Catch (DPL::DB::SqlConnection::Exception::Base) {
-                LogDebug("Fail to connect DB");
-                return FALSE;
-            }
-        }
+            case 's':
+            case 'k':
+                strncpy(temp_arg, optarg, strlen(optarg));
+                op = next_opt;
+                break;
 
-        WidgetDAOReadOnlyList widgetList =
-                WrtDB::WidgetDAOReadOnly::getWidgetList();
-        FOREACH(dao, widgetList) {
-            WrtDB::WidgetGUID d_guid = (*dao)->getGUID();
-            DPL::OptionalString d_pkgname = (*dao)->getPkgname();
-            if (!d_guid.IsNull() &&
-                !strcmp(DPL::ToUTF8String(*d_guid).c_str(), temp_arg))
-            {
-                DPL::Optional<DPL::String> package_name = (*dao)->getPkgname();
-                temp = DPL::ToUTF8String(*package_name);
+            case 't':
+                timeout = atoi(optarg);
+                if (timeout < 0 ) {
+                    timeout = TIMEOUT_DEFAULT;
+                }
                 break;
-            }
-            if (!strcmp(DPL::ToUTF8String(*d_pkgname).c_str(), temp_arg)) {
-                DPL::Optional<DPL::String> package_name = (*dao)->getPkgname();
-                temp = DPL::ToUTF8String(*package_name);
+
+            case 'd':
+                // create service
+                ret = service_create(&serviceHandle);
+                if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
+                    LogError("Fail to create service");
+                    return FALSE;
+                }
+
+                // set debug mode
+                ret = service_add_extra_data(serviceHandle,
+                                             "debug",
+                                             "true");
+                if (SERVICE_ERROR_NONE != ret) {
+                    LogError("Fail to set debug mode [" << ret << "]");
+                    service_destroy(serviceHandle);
+                    return FALSE;
+                }
+
+                // set pid
+                snprintf(pid, sizeof(pid), "%d", getpid());
+                ret = service_add_extra_data(serviceHandle,
+                                             "pid",
+                                             pid);
+                if (SERVICE_ERROR_NONE != ret) {
+                    LogError("Fail to set pid [" << ret << "]");
+                    service_destroy(serviceHandle);
+                    return FALSE;
+                }
+                isDebugMode = true;
                 break;
-            }
-        }
 
-        if (!temp.empty()) {
-            strncpy(pkgname, temp.c_str(), strlen(temp.c_str()));
-        } else {
-            printf("result: %s\n", "failed");
-            return -1;
-        }
-    }
+            case 'v':
+                strncpy(temp_arg, optarg, strlen(optarg));
+                if(!attachDbConnection()) return FALSE;
+                if (!strcmp("1", temp_arg)) {
+                    WrtDB::GlobalDAO::SetDeveloperMode(true);
+                } else {
+                    WrtDB::GlobalDAO::SetDeveloperMode(false);
+                }
+                break;
+            case 'c':
+                strncpy(temp_arg, optarg, strlen(optarg));
+                if(!attachDbConnection()) return FALSE;
+                if(!strcmp("1", temp_arg)) {
+                    WrtDB::GlobalDAO::setComplianceMode(true);
+                } else {
+                    WrtDB::GlobalDAO::setComplianceMode(false);
+                }
+                break;
+            case 'i':
+                strncpy(temp_arg, optarg, strlen(optarg));
+                if(!attachDbConnection()) return FALSE;
+                WrtDB::GlobalDAO::setComplianceFakeImei(temp_arg);
+                break;
+            case 'm':
+                strncpy(temp_arg, optarg, strlen(optarg));
+                if(!attachDbConnection()) return FALSE;
+                WrtDB::GlobalDAO::setComplianceFakeMeid(temp_arg);
+                break;
 
-    if (op == 's') {
-        /* check if this is request for debug mode, or not */
-        if (true == isDebugMode) {
-            /* wait for return from the widget */
-            sigemptyset(&sigact.sa_mask);
-            sigact.sa_flags = SA_SIGINFO;
-            sigact.sa_restorer = NULL;
-            sigact.sa_sigaction = sighandler;
+            case -1:
+                break;
 
-            if (sigaction(SIGRTMIN, &sigact, 0) == 1) {
-                printf("result: %s\n", "failed");
-                return -1;
+            default:
+                print_help(stdout, 0);
+                break;
             }
-        } else {
-            // case of "-d" option, service_create is already allocated
-            // create service
-            ret = service_create(&serviceHandle);
-            if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
-                printf("result: %s\n", "failed");
-                return -1;
+        } while (next_opt != -1);
+
+        if ((op == 's') || (op == 'k')) {
+            std::string temp;
+
+            if (NULL == g_dbConnection.get()) {
+                Try {
+                    g_dbConnection.reset(new DBConnection());
+                    g_dbConnection->AttachDatabase();
+                }
+                Catch (DPL::DB::SqlConnection::Exception::Base) {
+                    LogDebug("Fail to connect DB");
+                    return FALSE;
+                }
             }
-        }
 
-        if (strlen(pkgname) > 0) {
-            // do setuid to '5000' uid to communicate
-            //with webapp using RT signal.
-            gid_t group_list[1];
-            group_list[0] = LOGGING_DEFAULT_GID;
+            WidgetDAOReadOnlyList widgetList =
+                    WrtDB::WidgetDAOReadOnly::getWidgetList();
+            FOREACH(dao, widgetList) {
+                WrtDB::WidgetGUID d_guid = (*dao)->getGUID();
+                DPL::OptionalString d_pkgname = (*dao)->getPkgname();
+                if (!d_guid.IsNull() &&
+                    !strcmp(DPL::ToUTF8String(*d_guid).c_str(), temp_arg))
+                {
+                    DPL::Optional<DPL::String> package_name = (*dao)->getPkgname();
+                    temp = DPL::ToUTF8String(*package_name);
+                    break;
+                }
+                if (!strcmp(DPL::ToUTF8String(*d_pkgname).c_str(), temp_arg)) {
+                    DPL::Optional<DPL::String> package_name = (*dao)->getPkgname();
+                    temp = DPL::ToUTF8String(*package_name);
+                    break;
+                }
+            }
 
-            if(setgroups(sizeof(group_list), group_list) < 0) {
+            if (!temp.empty()) {
+                strncpy(pkgname, temp.c_str(), strlen(temp.c_str()));
+            } else {
                 printf("result: %s\n", "failed");
                 return -1;
             }
+        }
 
-            if(setreuid(WEBAPP_DEFAULT_UID, WEBAPP_DEFAULT_GID) < 0) {
-                printf("result: %s\n", "failed");
-                return -1;
+        if (op == 's') {
+            /* check if this is request for debug mode, or not */
+            if (true == isDebugMode) {
+                /* wait for return from the widget */
+                sigemptyset(&sigact.sa_mask);
+                sigact.sa_flags = SA_SIGINFO;
+                sigact.sa_restorer = NULL;
+                sigact.sa_sigaction = sighandler;
+
+                if (sigaction(SIGRTMIN, &sigact, 0) == 1) {
+                    printf("result: %s\n", "failed");
+                    return -1;
+                }
+            } else {
+                // case of "-d" option, service_create is already allocated
+                // create service
+                ret = service_create(&serviceHandle);
+                if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
+                    printf("result: %s\n", "failed");
+                    return -1;
+                }
             }
 
-            // set package
-            ret = service_set_package(serviceHandle, pkgname);
-            if (SERVICE_ERROR_NONE != ret) {
-                printf("result: %s\n", "failed");
+            if (strlen(pkgname) > 0) {
+                // do setuid to '5000' uid to communicate
+                //with webapp using RT signal.
+                gid_t group_list[1];
+                group_list[0] = LOGGING_DEFAULT_GID;
+
+                if(setgroups(sizeof(group_list), group_list) < 0) {
+                    printf("result: %s\n", "failed");
+                    return -1;
+                }
+
+                if(setreuid(WEBAPP_DEFAULT_UID, WEBAPP_DEFAULT_GID) < 0) {
+                    printf("result: %s\n", "failed");
+                    return -1;
+                }
+
+                // set package
+                ret = service_set_package(serviceHandle, pkgname);
+                if (SERVICE_ERROR_NONE != ret) {
+                    printf("result: %s\n", "failed");
+                    service_destroy(serviceHandle);
+                    return -1;
+                }
+
+                //launch service
+                ret = service_send_launch_request(serviceHandle, NULL, NULL);
+                if (SERVICE_ERROR_NONE != ret) {
+                    printf("result: %s\n", "failed");
+                    service_destroy(serviceHandle);
+                    return -1;
+                }
+
                 service_destroy(serviceHandle);
+            } else {
+                printf("result: %s\n", "failed");
                 return -1;
             }
 
-            //launch service
-            ret = service_send_launch_request(serviceHandle, NULL, NULL);
-            if (SERVICE_ERROR_NONE != ret) {
+            if (true == isDebugMode) {
+                // wait RTS signal from widget by 5 second
+                sleep(timeout);
                 printf("result: %s\n", "failed");
-                service_destroy(serviceHandle);
                 return -1;
             }
+            // This text should be showed for IDE
+            printf("result: %s\n", "launched");
+            return 0;
+        } else if (op == 'k') {
+            bool isRunning = false;
 
-            service_destroy(serviceHandle);
-        } else {
-            printf("result: %s\n", "failed");
-            return -1;
-        }
-
-        if (true == isDebugMode) {
-            // wait RTS signal from widget by 5 second
-            sleep(timeout);
-            printf("result: %s\n", "failed");
-            return -1;
-        }
-        // This text should be showed for IDE
-        printf("result: %s\n", "launched");
-        return 0;
-    } else if (op == 'k') {
-        bool isRunning = false;
-
-        //checks whether the application is running
-        ret = app_manager_is_running(pkgname, &isRunning);
-        if (APP_MANAGER_ERROR_NONE != ret) {
-            printf("result: %s\n", "failed");
-            return -1;
-        }
-
-        if (true == isRunning) {
-            // get app_context for running application
-            // app_context must be released with app_context_destroy
-            app_context_h appCtx = NULL;
-            ret = app_manager_get_app_context(pkgname, &appCtx);
+            //checks whether the application is running
+            ret = app_manager_is_running(pkgname, &isRunning);
             if (APP_MANAGER_ERROR_NONE != ret) {
                 printf("result: %s\n", "failed");
                 return -1;
             }
 
-            // terminate app_context_h
-            ret = app_manager_terminate_app(appCtx);
-            if (APP_MANAGER_ERROR_NONE != ret) {
-                printf("result: %s\n", "failed");
-                app_context_destroy(appCtx);
-                return -1;
+            if (true == isRunning) {
+                // get app_context for running application
+                // app_context must be released with app_context_destroy
+                app_context_h appCtx = NULL;
+                ret = app_manager_get_app_context(pkgname, &appCtx);
+                if (APP_MANAGER_ERROR_NONE != ret) {
+                    printf("result: %s\n", "failed");
+                    return -1;
+                }
+
+                // terminate app_context_h
+                ret = app_manager_terminate_app(appCtx);
+                if (APP_MANAGER_ERROR_NONE != ret) {
+                    printf("result: %s\n", "failed");
+                    app_context_destroy(appCtx);
+                    return -1;
+                } else {
+                    printf("result: %s\n", "killed");
+                    app_context_destroy(appCtx);
+                    return 0;
+                }
             } else {
-                printf("result: %s\n", "killed");
-                app_context_destroy(appCtx);
+                printf("result: %s\n", "App isn't running");
                 return 0;
             }
-        } else {
-            printf("result: %s\n", "App isn't running");
-            return 0;
         }
-    }
 
-    return 0;
+        return 0;
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
 }
 
 static void sighandler(int signo, siginfo_t *si, void* /*data*/)