Add signal handler 77/128677/11 accepted/tizen/unified/20170511.173403 submit/tizen/20170511.080142
authorJongHeon Choi <j-h.choi@samsung.com>
Thu, 11 May 2017 05:03:17 +0000 (14:03 +0900)
committerJongHeon Choi <j-h.choi@samsung.com>
Thu, 11 May 2017 06:14:32 +0000 (15:14 +0900)
Change-Id: I46bd2e0867261675c3f04352330df9022526cf20

NativeLauncher/CMakeLists.txt [changed mode: 0755->0644]
NativeLauncher/launcher/dotnet_signal_handler.cc [new file with mode: 0644]
NativeLauncher/launcher/dotnet_signal_handler.h [new file with mode: 0644]
NativeLauncher/launcher/main.cc
packaging/dotnet-launcher.spec [changed mode: 0755->0644]

old mode 100755 (executable)
new mode 100644 (file)
index e453d9a..abbf4c2
@@ -46,6 +46,10 @@ IF(USE_MANAGED_LAUNCHER STREQUAL "ENABLE")
     ADD_DEFINITIONS("-DUSE_MANAGED_LAUNCHER")
 ENDIF(USE_MANAGED_LAUNCHER)
 
+IF(RAISE_DEFAULT_SIGNAL_HANDLER STREQUAL "ENABLE")
+    ADD_DEFINITIONS("-DRAISE_DEFAULT_SIGNAL_HANDLER")
+ENDIF(RAISE_DEFAULT_SIGNAL_HANDLER)
+
 OPTION(NOT_USE_FUNCTION "Remove build warning" OFF)
 IF(NOT_USE_FUNCTION)
     ADD_DEFINITIONS("-DNOT_USE_FUNCTION")
@@ -74,6 +78,7 @@ SET(${DOTNET_LAUNCHER}_SOURCE_FILES
     launcher/main.cc
     util/utils.cc
     launcher/launcher.cc
+    launcher/dotnet_signal_handler.cc
     launcher/dotnet/dotnet_launcher.cc
 )
 ADD_EXECUTABLE(${DOTNET_LAUNCHER} ${${DOTNET_LAUNCHER}_SOURCE_FILES})
diff --git a/NativeLauncher/launcher/dotnet_signal_handler.cc b/NativeLauncher/launcher/dotnet_signal_handler.cc
new file mode 100644 (file)
index 0000000..783f6c7
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "dotnet_signal_handler.h"
+
+#include "log.h"
+
+#include <cstdio>
+#include <vector>
+
+#include <signal.h>
+#include <iostream>
+#include <exception>
+#include <execinfo.h>
+
+using namespace std;
+
+#define CALLSTACK_SIZE 30
+
+std::vector<std::string> backtraceStr;
+char **backtraceStrings;
+int backtracePtrs;
+
+static void printBacktrace()
+{
+       if (backtraceStr.size() > 0) {
+               _ERR("Backtrace returned %d addresses :", backtraceStr.size());
+
+               for (unsigned int i = 0; i < backtraceStr.size(); i++) {
+                       _ERR("[Backtrace #%d] : %s", i, backtraceStr[i].c_str());
+               }
+       }
+
+       backtraceStr.clear();
+}
+
+static bool nativeCrashCheck()
+{
+       int i;
+       void *buf[CALLSTACK_SIZE + 1];
+
+       backtracePtrs = backtrace(buf, CALLSTACK_SIZE);
+       if (backtracePtrs == 0) {
+               _ERR("No backtrace captured");
+               return false;
+       }
+
+       backtraceStrings = backtrace_symbols(buf, backtracePtrs);
+
+       if (backtraceStrings == NULL) {
+               _ERR("No backtrace captured");
+               return false;
+       }
+
+       backtraceStr.clear();
+
+       for (i = backtracePtrs - 1; i >= 0; i--) {
+               if (strstr(backtraceStrings[i], "__default_rt_sa_restorer") != NULL)
+                       return backtraceStr.size() > 0;
+
+               backtraceStr.push_back(std::string(backtraceStrings[i]));
+       }
+
+       return true;
+}
+
+static void onSigabrt(int signum)
+{
+       _ERR("<<< SIGABRT %d >>>", signum);
+
+       backtracePtrs = 0;
+       backtraceStrings = NULL;
+
+       if (nativeCrashCheck()) {
+               printBacktrace();
+#ifdef RAISE_DEFAULT_SIGNAL_HANDLER
+               SIG_DFL(signum);
+#endif
+       } else {
+               _ERR("Crash from managed code");
+       }
+
+       if (backtraceStrings != NULL) {
+               free(backtraceStrings);
+               backtraceStrings = NULL;
+       }
+
+       exit(0);
+}
+
+static void onSigsegv(int signum)
+{
+       _ERR("<<< SIGSEGV %d >>>", signum);
+
+       backtracePtrs = 0;
+       backtraceStrings = NULL;
+
+       if (nativeCrashCheck()) {
+               printBacktrace();
+#ifdef RAISE_DEFAULT_SIGNAL_HANDLER
+               SIG_DFL(signum);
+#endif
+       } else {
+               _ERR("Crash from managed code");
+       }
+
+       if (backtraceStrings != NULL) {
+               free(backtraceStrings);
+               backtraceStrings = NULL;
+       }
+
+       exit(0);
+}
+
+static void onSigtrap(int signum)
+{
+       _ERR("<<< SIGTRAP %d >>>", signum);
+
+       exit(0);
+}
+
+void registerSignalHandler()
+{
+       _DBG("Register signal handler");
+
+       if (SIG_ERR == signal(SIGABRT, &onSigabrt) ||
+               SIG_ERR == signal(SIGSEGV, &onSigsegv) ||
+               SIG_ERR == signal(SIGTRAP, &onSigtrap)) {
+               perror("[dotnet-launcher] signal register error\n");
+               _ERR("Signal register error");
+       }
+}
diff --git a/NativeLauncher/launcher/dotnet_signal_handler.h b/NativeLauncher/launcher/dotnet_signal_handler.h
new file mode 100644 (file)
index 0000000..9cbb62e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __DOTNET_SIGNAL_HANDLER__
+#define __DOTNET_SIGNAL_HANDLER__
+
+void registerSignalHandler();
+
+#endif /* __DOTNET_SIGNAL_HANDLER__ */
index 2bbda72..7063a2d 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "dotnet/dotnet_launcher.h"
+#include "dotnet_signal_handler.h"
 #include "utils.h"
 #include "log.h"
 
@@ -40,6 +41,8 @@ static std::string StandaloneOption("--standalone");
 
 int main(int argc, char *argv[])
 {
+       registerSignalHandler();
+
        int i;
        bool standalone = false;
        const char* standalonePath = nullptr;
old mode 100755 (executable)
new mode 100644 (file)
index 847558a..09e3e41
@@ -63,6 +63,11 @@ launching dotnet apps without dotent runtime installed
        %define USE_MANAGED_LAUNCHER ENABLE
 %endif
 
+%define raise_default_signal_handler 0
+%if %{raise_default_signal_handler}
+       %define RAISE_DEFAULT_SIGNAL_HANDLER ENABLE
+%endif
+
 %build
 cmake \
        -DCMAKE_INSTALL_PREFIX=%{_prefix} \
@@ -82,6 +87,7 @@ cmake \
        -DINSTALL_MDPLUGIN_DIR=%{_install_mdplugin_dir} \
        -DVERSION=%{version} \
        -DUSE_MANAGED_LAUNCHER=%{?USE_MANAGED_LAUNCHER:%USE_MANAGED_LAUNCHER} \
+       -DRAISE_DEFAULT_SIGNAL_HANDLER=%{?RAISE_DEFAULT_SIGNAL_HANDLER:%RAISE_DEFAULT_SIGNAL_HANDLER} \
        -DNATIVE_LIB_DIR=%{_native_lib_dir} \
        NativeLauncher