donot create coredump file for unhandled exception
[platform/core/dotnet/launcher.git] / NativeLauncher / launcher / dotnet / dotnet_launcher.cc
index 0fb373a..18a5c3e 100644 (file)
 
 
 #include <dlfcn.h>
+#include <signal.h>
 
 #include <string>
 #include <fstream>
 #include <vector>
+#include <sstream>
 
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -36,6 +38,7 @@
 #include "log_manager.h"
 
 #define PLUGIN_PATH "/usr/share/dotnet.tizen/lib/libdotnet_plugin.so"
+#define ENV_FILE_PATH "/usr/share/dotnet.tizen/lib/coreclr_env.list"
 
 namespace tizen {
 namespace runtime {
@@ -83,6 +86,78 @@ static std::string getExtraNativeLibDirs(const std::string& appRoot)
        return candidate;
 }
 
+
+static std::vector<std::string> __envList;
+
+static void setEnvFromFile()
+{
+       std::string envList;
+       std::ifstream inFile(ENV_FILE_PATH);
+
+       __envList.clear();
+
+       if (inFile) {
+               _INFO("coreclr_env.list is found");
+               inFile >> envList;
+
+               std::istringstream ss(envList);
+               std::string token;
+
+               while (std::getline(ss, token, ':')) {
+                       if (!token.empty()) {
+                               __envList.push_back(token);
+                       }
+               }
+
+               for (unsigned int i = 0; i < __envList.size(); i++) {
+                       putenv(const_cast<char *>(__envList[i].c_str()));
+               }
+       } else {
+               _INFO("coreclr_env.list file is not found. skip");
+       }
+}
+
+struct sigaction sig_abrt_new;
+struct sigaction sig_abrt_old;
+
+static bool checkOnSigabrt = false;
+static void onSigabrt(int signum)
+{
+    fprintf(stderr, "onSigabrt is called!!!\n");
+
+    if (checkOnSigabrt) {
+        fprintf(stderr, "SIGABRT is already handled. Go to exit\n");
+        exit(0);
+    }
+
+    if (hasException()) {
+        fprintf(stderr, "Unhandled exception is occured. Ignore coredump creation and terminate normally\n");
+        exit(0);
+    } else {
+        fprintf(stderr, "SIGABRT from native. raise(%d)\n", signum);
+        checkOnSigabrt = true;
+               if (sigaction(SIGABRT, &sig_abrt_old, NULL) == 0) {
+                       if (raise(signum) < 0) {
+                               fprintf(stderr, "Fail to raise SIGABRT\n");
+                       }
+               } else {
+                       fprintf(stderr, "Fail to set original SIGABRT handler\n");
+               }
+    }
+}
+
+static void registerSigHandler()
+{
+       sig_abrt_new.sa_handler = onSigabrt;
+       if (sigemptyset(&sig_abrt_new.sa_mask) == 0) {
+               _ERR("Fail to initialize signal set");
+       }
+
+       if (sigaction(SIGABRT, &sig_abrt_new, &sig_abrt_old) < 0) {
+               _ERR("Fail to add sig handler");
+       }
+}
+
 CoreRuntime::CoreRuntime(const char* mode) :
        initializeClr(nullptr),
        executeAssembly(nullptr),
@@ -92,10 +167,23 @@ CoreRuntime::CoreRuntime(const char* mode) :
        __hostHandle(nullptr),
        __domainId(-1),
        fd(0),
-       __mode(mode),
        __initialized(false)
 {
-       _DBG("Constructor called!!");
+       _INFO("Constructor called!!");
+
+       // plugin initialize should be called before start loader mainloop.
+       // In case of VD plugins, attaching secure zone is done in the plugin_initialize().
+       // When attaching to a secure zone, if there is a created thread, it will failed.
+       // So, plugin initialize should be called before mainloop start.
+       if (initializePluginManager(mode) < 0) {
+               _ERR("Failed to initialize PluginManager");
+       }
+
+       if (pluginHasLogControl()) {
+               __enableLogManager = false;
+       } else {
+               __enableLogManager = true;
+       }
 }
 
 CoreRuntime::~CoreRuntime()
@@ -129,29 +217,29 @@ int CoreRuntime::initialize(bool standalone)
        putenv(const_cast<char *>("UNW_ARM_UNWIND_METHOD=6"));
 #endif // __arm__
 
-       if (initializePluginManager(__mode) < 0) {
-               _ERR("Failed to initialize PluginManager");
-               return -1;
-       }
+       // read string from external file and set them to environment value.
+       setEnvFromFile();
 
        if (initializePathManager(std::string(), std::string(), std::string()) < 0) {
                _ERR("Failed to initialize PathManager");
                return -1;
        }
 
-       if (initializeLogManager() < 0) {
-               _ERR("Failed to initnialize LogManager");
-               return -1;
-       }
+       if (__enableLogManager) {
+               if (initializeLogManager() < 0) {
+                       _ERR("Failed to initnialize LogManager");
+                       return -1;
+               }
 
-       if (redirectFD() < 0) {
-               _ERR("Failed to redirect FD");
-               return -1;
-       }
+               if (redirectFD() < 0) {
+                       _ERR("Failed to redirect FD");
+                       return -1;
+               }
 
-       if (runLoggingThread() < 0) {
-               _ERR("Failed to create and run logging thread to redicrect log");
-               return -1;
+               if (runLoggingThread() < 0) {
+                       _ERR("Failed to create and run logging thread to redicrect log");
+                       return -1;
+               }
        }
 
        std::string libCoreclr(concatPath(getRuntimeDir(), "libcoreclr.so"));
@@ -179,7 +267,7 @@ int CoreRuntime::initialize(bool standalone)
 
 #undef CORELIB_RETURN_IF_NOSYM
 
-       _DBG("libcoreclr dlopen and dlsym success");
+       _INFO("libcoreclr dlopen and dlsym success");
 
        if (!standalone)
                pluginPreload();
@@ -200,6 +288,8 @@ int CoreRuntime::initialize(bool standalone)
 
        __initialized = true;
 
+       _INFO("CoreRuntime initialize success");
+
        return 0;
 }
 
@@ -241,7 +331,7 @@ bool CoreRuntime::initializeCoreClr(const char* appId,
 
        pluginSetCoreclrInfo(__hostHandle, __domainId, createDelegate);
 
-       _DBG("Initialize core clr success");
+       _INFO("Initialize core clr success");
        return true;
 }
 
@@ -265,7 +355,9 @@ void CoreRuntime::dispose()
        finalizePluginManager();
        finalizePathManager();
 
-       _DBG("Dotnet runtime disposed");
+       __envList.clear();
+
+       _INFO("Dotnet runtime disposed");
 }
 
 int CoreRuntime::launch(const char* appId, const char* root, const char* path, int argc, char* argv[])
@@ -285,11 +377,15 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i
                return -1;
        }
 
-       // launchpad override stdout and stderr to journalctl before launch application.
-       // we have to re-override that to input pipe for logging thread.
-       if (redirectFD() < 0) {
-               _ERR("Failed to redirect FD");
-               return -1;
+       if (__enableLogManager) {
+               // launchpad override stdout and stderr to journalctl before launch application.
+               // we have to re-override that to input pipe for logging thread.
+               if (redirectFD() < 0) {
+                       _ERR("Failed to redirect FD");
+                       return -1;
+               }
+
+               registerSigHandler();
        }
 
        pluginSetAppInfo(appId, path);
@@ -301,6 +397,8 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i
 
        pluginBeforeExecute();
 
+       _INFO("execute assembly : %s", path);
+
        unsigned int ret = 0;
        int st = executeAssembly(__hostHandle, __domainId, argc, (const char**)argv, path, &ret);
        if (st < 0)