Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:52:00 +0000 (01:52 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:52:00 +0000 (01:52 +0900)
12 files changed:
AUTHORS [new file with mode: 0755]
CMakeLists.txt [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0755]
NOTICE [new file with mode: 0755]
core-launcher/CMakeLists.txt [new file with mode: 0644]
core-launcher/core-launcher.c [new file with mode: 0644]
coredumpctrl.sh [new file with mode: 0755]
packaging/sys-assert.spec [new file with mode: 0644]
sys-assert.manifest [new file with mode: 0644]
sys-assert/CMakeLists.txt [new file with mode: 0644]
sys-assert/src/sys-assert.c [new file with mode: 0755]
sys-assert/src/sys-assert.h [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
new file mode 100755 (executable)
index 0000000..2190840
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+juho son <juho80.son at samsung dot com>
+Suchang Woo <suchang.woo at samsung dot com>
+kyungmin Park <kyungmin Park at samsung dot com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d79cf8d
--- /dev/null
@@ -0,0 +1,8 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(sys-assert)
+ADD_SUBDIRECTORY(core-launcher)
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/coredumpctrl.sh DESTINATION /usr/bin
+               PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+               GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100755 (executable)
index 0000000..8aa906c
--- /dev/null
@@ -0,0 +1,205 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
+
+
diff --git a/NOTICE b/NOTICE
new file mode 100755 (executable)
index 0000000..0e0f016
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/core-launcher/CMakeLists.txt b/core-launcher/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e285bac
--- /dev/null
@@ -0,0 +1,37 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(core-launcher C)
+
+SET(PROJECT_NAME "core-launcher")
+SET(SRCS core-launcher.c)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+FOREACH(flag ${pkgs-common_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpie")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DEAPI")
+ADD_DEFINITIONS("-DDEBUG_ON")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs-common_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/core-launcher/core-launcher.c b/core-launcher/core-launcher.c
new file mode 100644 (file)
index 0000000..c1d468e
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * CORE-LAUNCHER
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <sys/stat.h>
+#include <sys/statfs.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/mount.h>
+#include <sys/un.h>
+#include <sys/types.h>
+
+#define CRASH_NOTI_DIR      "/opt/share/crash"
+#define CRASH_NOTI_FILE     "curbs.log"
+#define CRASH_NOTI_PATH    CRASH_NOTI_DIR"/"CRASH_NOTI_FILE
+
+#define CRASH_CHECK_COREDUMP_NUM (10)
+#define CRASH_CHECK_SIZE (1024 * 512)
+#define CRASH_CHECK_DISK_PATH   "/opt/usr"
+#define CRASH_INFO_PATH    "/opt/share/crash/info"
+#define CRASH_CORE_PATH "/opt/usr/share/crash/core"
+#define CRASH_SAVE_PATH "/opt/usr/share/crash"
+#define CRASH_DUMP_PATH "/opt/usr/share/crash/dump"
+#define CRASH_REPORT_PATH   "/opt/usr/share/crash/report"
+
+#define TIZEN_OPT_USR_MOUNT "/dev/mmcblk0p7"
+#define TIZEN_OPT_USR_TYPE "ext4"
+
+#define CRASH_TIME_MAX 65
+#define CRASH_INFO_EXPAND_SIZE 5
+#define CRASH_CORE_INFO_MATCH_TIMEGAP 10
+#define BUF_SIZE 1024
+#define PATH_MAX 4096
+
+#define DEBUG_CORE_LAUNCHER
+
+static ssize_t safewrite(int fd, const void *buf, size_t count)
+{
+       ssize_t n;
+       do {
+               n = write(fd, buf, count);
+       } while (n < 0 && errno == EINTR);
+       return n;
+}
+
+static bool _check_previous_coredump_num(char *check_dir, int check_num)
+{
+       DIR *dp;
+       struct dirent *de;
+       int count = 0;
+
+       if (check_dir == NULL)
+               return false;
+       if (check_num == 0)
+               return true;
+       dp = opendir(check_dir);
+       if (dp == NULL) {
+               fprintf(stderr, "error opendir %s\n", check_dir);
+               return false;
+       }
+       while (de = readdir(dp)) {
+               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+                       continue;
+               if (de->d_ino != 0 )
+                       count++;
+       }
+       closedir(dp);
+       if (check_num < count)
+               return false;
+       else
+               return true;
+}
+/* check disk available size */
+static bool _check_disk_available(char *mount_dir, int check_size)
+{
+       struct statfs lstatfs;
+
+       if (mount_dir == NULL)
+               return false;
+       if (check_size == 0)
+               return true;
+       if (statfs(mount_dir, &lstatfs) < 0) {
+               fprintf(stderr, "can't get statfs %s\n", mount_dir);
+               return false;
+       } else {
+               if (check_size <=
+                               lstatfs.f_bavail * (lstatfs.f_bsize/1024)) {
+                       return true;
+               } else {
+                       fprintf(stderr, "NO %d < %d\n", check_size,
+                                       (int)(lstatfs.f_bavail * (lstatfs.f_bsize/1024)));
+                       return false;
+               }
+       }
+}
+static bool _check_crash_name_timesec(char *filename,
+               char *pid, char *timesec)
+{
+       if (filename == NULL || pid == NULL || timesec == NULL)
+               return false;
+       int pid_len = 0;
+       int times_len = 0;
+       long infotime = 0;
+       long coretime = 0;
+       long timegap = 0;
+       char tbuf[CRASH_TIME_MAX] = {0, };
+       int len = strlen(filename);
+       int i = 0;
+       for (i = 0; i < len; i++) {
+               if (filename[i] == '_') {
+                       pid_len = i;
+                       times_len = len - i - CRASH_INFO_EXPAND_SIZE;
+                       break;
+               }
+       }
+       if (!strncmp(pid, filename, i)) {
+               strncpy(tbuf, &(filename[i+1]), times_len);
+               infotime = atol(tbuf);
+               coretime = atol(timesec);
+               timegap = labs(infotime - coretime);
+               if (timegap < CRASH_CORE_INFO_MATCH_TIMEGAP)
+                       return true;
+               return false;
+       }
+       return false;
+}
+static bool check_crash_libsysinfo(char *pid, char *timesec)
+{
+       DIR *dp;
+       struct dirent *de;
+       dp = opendir(CRASH_INFO_PATH);
+       if (dp == NULL) {
+               fprintf(stderr, "error opendir %s\n", CRASH_INFO_PATH);
+               return false;
+       }
+       while (de = readdir(dp)) {
+               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+                       continue;
+               if (_check_crash_name_timesec(de->d_name,
+                                       pid, timesec) == 1) {
+                       closedir(dp);
+                       return true;
+               }
+       }
+       closedir(dp);
+       return false;
+}
+/*
+ * 1  2  3  4
+ * %e %t %p %s
+ */
+int main(int argc, char *argv[])
+{
+       int fd_curbs;       /* for inotify */
+       int fd_coredump;       /* for core dump */
+       char buf[BUF_SIZE];
+       int i;
+       bool haveinfo = false;
+       bool filesaveon = false;
+       int corefilesize = 0;
+       char corefile[PATH_MAX] = {0, }; /* corefile buf */
+       char notimsg[BUF_SIZE] = {0, }; /* crash noti message */
+       ssize_t nread;
+       const unsigned long mntflags = 0;
+#ifdef DEBUG_CORE_LAUNCHER
+       FILE *tfp;
+       char cwd[PATH_MAX];
+       snprintf(cwd, PATH_MAX,
+                       "/tmp/%s_%s_%s_%s.info",
+                       argv[1], argv[2], argv[3], argv[4]);
+       tfp = fopen(cwd, "w+");
+       if (tfp == NULL)
+               exit(EXIT_FAILURE);
+       fprintf(tfp, "argc=%d\n", argc);
+       for (i = 0; i < argc; i++)
+               fprintf(tfp, "argc[%d]=<%s>\n", i, argv[i]);
+#endif
+       /* check that process name is crash-worker or crash-popup, because prevent infinite called */
+       if (!strcmp(argv[1], "crash-worker") || !strcmp(argv[1], "crash-popup")) {
+#ifdef DEBUG_CORE_LAUNCHER
+               fclose(tfp);
+#endif
+               exit(EXIT_SUCCESS);
+       }
+       /* check already know crash is reported and triggerd by libsys-assert lib */
+       haveinfo = check_crash_libsysinfo(argv[3], argv[2]);
+       /* check core dump path for saving */
+       if (access(CRASH_CORE_PATH, F_OK) != 0) {
+               /* if can't access core dump path, try mount that */
+               if (mount(TIZEN_OPT_USR_MOUNT,
+                                       CRASH_CHECK_DISK_PATH,
+                                       TIZEN_OPT_USR_TYPE, mntflags, NULL) != 0)
+                       sleep(2);
+               else
+                       filesaveon = true;
+
+       /* one more check core dump path for saving */
+               if (access(CRASH_CORE_PATH, F_OK) != 0)
+                       filesaveon = false;
+       } else
+               filesaveon = true;
+
+       /* check that disk extra sapce is available */
+       if (_check_disk_available(CRASH_CHECK_DISK_PATH,
+                               CRASH_CHECK_SIZE) == true) {
+               /* check previous coredump file number,
+                  because if system_server was dead,
+                  crash-worker didn't working.
+                  so coredump stacked an unlimited number*/
+               filesaveon = _check_previous_coredump_num(CRASH_CORE_PATH,
+                               CRASH_CHECK_COREDUMP_NUM);
+       }
+
+       if (filesaveon == true) {
+               snprintf(corefile, PATH_MAX,
+                               "%s/%s_%s_%s.core",
+                               CRASH_CORE_PATH, argv[3], argv[4], argv[1]);
+               fd_coredump = open(corefile, O_WRONLY | O_SYNC | O_CREAT | O_TRUNC, 0644);
+               if (fd_coredump < 0) {
+                       fprintf(stderr,
+                                       "[core-launcher]cannot open core dump file!\n");
+               } else {
+                       corefilesize = 0;
+                       while ((nread = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) {
+                               corefilesize += nread;
+                               safewrite(fd_coredump, buf, nread);
+                       }
+                       fsync(fd_coredump);
+                       close(fd_coredump);
+               }
+       }
+
+       if (haveinfo == false) {
+               /* NOTIFY CRASH */
+               fd_curbs = open(CRASH_NOTI_PATH, O_RDWR | O_APPEND);
+               if (fd_curbs < 0) {
+                       fprintf(stderr,
+                                       "[core-launcher]cannot make %s !\n",
+                                       CRASH_NOTI_PATH);
+               } else {
+                       snprintf(notimsg, BUF_SIZE,
+                                       "C|%s|%s|%s|%s|%d\n",
+                                       argv[1], argv[2], argv[3], argv[4], strlen(argv[1]) + strlen(argv[4]));
+                       write(fd_curbs, notimsg, strlen(notimsg));
+                       close(fd_curbs);
+               }
+       }
+#ifdef DEBUG_CORE_LAUNCHER
+       fprintf(tfp, "haveinfo check(%d) %s %s\n", haveinfo, argv[1], argv[2]);
+       if (filesaveon == true)
+               fprintf(tfp, "Total bytes in core dump: %d\n", corefilesize);
+       else
+               fprintf(tfp, "We didn't save core dump\n");
+       fclose(tfp);
+#endif
+       exit(EXIT_SUCCESS);
+}
+
diff --git a/coredumpctrl.sh b/coredumpctrl.sh
new file mode 100755 (executable)
index 0000000..52a9065
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/sh
+MODE=none
+VAL=none
+#echo "tizen_platform_coredump_control"
+case "$1" in
+get)
+       MODE=get
+;;
+set)
+       MODE=set
+;;
+
+*)
+echo "Usage: coredumpctrl.sh {get|set} {1|0}"
+exit 1
+esac
+
+if [ "$MODE" = "set" ]; then
+       case "$2" in
+       1)
+               VAL=1
+       ;;
+       0)
+               VAL=0
+       ;;
+       *)
+               echo "Usage: coredumpctrl.sh {get|set} {1|0}"
+       exit 1
+       esac
+fi
+
+if [ "$MODE" = "set" ]; then
+       if [ "$VAL" = "1" ] ; then
+               touch /opt/etc/.coredump 2>/dev/null
+       elif [ "$VAL" = "0" ] ; then
+               rm -f /opt/etc/.coredump 2>/dev/null
+       fi
+       echo "You must reboot this target to apply the change!"
+else
+       if [ -e "/opt/etc/.coredump" ]; then
+               echo 1
+       else
+               echo 0
+       fi
+fi
+
+exit 0
diff --git a/packaging/sys-assert.spec b/packaging/sys-assert.spec
new file mode 100644 (file)
index 0000000..238c712
--- /dev/null
@@ -0,0 +1,60 @@
+Name:       sys-assert
+Summary:    libsys-assert (shared object).
+Version:    0.3.2
+Release:    5
+Group:      Framework/system
+License:    Apache License, Version 2.0
+Source0:    %{name}-%{version}.tar.gz
+
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  cmake
+Requires(post): coreutils
+
+%description
+libsys-assert (shared object).
+
+%prep
+%setup -q
+
+%build
+export CFLAGS+=" -fPIC"
+%ifarch %{arm}
+    export CFLAGS+=" -DTARGET"
+%endif
+
+cmake . -DCMAKE_INSTALL_PREFIX=/usr
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+%post
+/sbin/ldconfig
+mkdir -p /opt/share/crash/info
+chown root:crash /opt/share/crash/info
+chmod 775 /opt/share/crash/info
+
+chown root:crash /opt/share/crash
+chmod 775 /opt/share/crash
+
+if [ -f %{_libdir}/rpm-plugins/msm.so ]; then
+       find /opt/share/crash -print0 | xargs -0 chsmack -a 'sys-assert::core'
+       find /opt/share/crash -type d -print0 | xargs -0 chsmack -t
+fi
+
+if [ ! -d /.build ]; then
+       echo "/usr/lib/libsys-assert.so" >> /etc/ld.so.preload
+       chmod 644 /etc/ld.so.preload
+fi
+
+%files
+%manifest sys-assert.manifest
+%{_bindir}/coredumpctrl.sh
+%{_bindir}/core-launcher
+%{_libdir}/libsys-assert.so
+/usr/share/license/%{name}
+
+
diff --git a/sys-assert.manifest b/sys-assert.manifest
new file mode 100644 (file)
index 0000000..2b983c7
--- /dev/null
@@ -0,0 +1,16 @@
+<manifest>
+       <define>
+               <domain name="sys-assert"/>
+               <provide>
+                       <label name="sys-assert::core"/>
+               </provide>
+       </define>
+       <request>
+               <domain name="sys-assert"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/lib/libsys-assert.so" label="_" exec_label="none"/>
+               <filesystem path="/etc/ld.so.preload" label="_" exec_label="none"/>
+               <filesystem path="/usr/bin/coredumpctrl.sh" label="_" exec_label="none"/>
+       </assign>
+</manifest>
diff --git a/sys-assert/CMakeLists.txt b/sys-assert/CMakeLists.txt
new file mode 100644 (file)
index 0000000..afba01d
--- /dev/null
@@ -0,0 +1,40 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sys-assert C)
+
+SET(SRCS
+       src/sys-assert.c
+)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(LIBDIR "\${prefix}/lib")
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DEAPI")
+ADD_DEFINITIONS("-DDEBUG_ON")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl)
+
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)
diff --git a/sys-assert/src/sys-assert.c b/sys-assert/src/sys-assert.c
new file mode 100755 (executable)
index 0000000..48608fc
--- /dev/null
@@ -0,0 +1,1246 @@
+/*
+ * SYS-ASSERT
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <execinfo.h>
+#include <dlfcn.h>
+#include <elf.h>
+#include <fcntl.h>
+#include <ucontext.h>
+#include <signal.h>
+#include <linux/unistd.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <time.h>
+#include <syslog.h>
+/* for PR_SET_DUMPABLE */
+#include <sys/prctl.h>
+#include "sys-assert.h"
+
+#define CMDLINE_PATH "/proc/self/cmdline"
+#define DBG_DIR        "/usr/lib/debug"
+#define EXE_PATH "/proc/self/exe"
+#define MAPS_PATH "/proc/self/maps"
+#define MEMINFO_PATH "/proc/meminfo"
+#define STATUS_PATH "/proc/self/status"
+
+#define CRASH_INFO_PATH "/opt/share/crash/info"
+#define CRASH_REPORT_PATH   "/opt/usr/share/crash/report"
+#define CRASH_NOTI_PATH        "/opt/share/crash/curbs.log"
+
+#define CRASH_CALLSTACKINFO_TITLE "Callstack Information"
+#define CRASH_CALLSTACKINFO_TITLE_E "End of Call Stack"
+#define CRASH_MAPSINFO_TITLE "Maps Information"
+#define CRASH_MAPSINFO_TITLE_E "End of Maps Information"
+#define CRASH_MEMINFO_TITLE "Memory Information"
+#define CRASH_REGISTERINFO_TITLE "Register Information"
+
+#define SUPPORT_LIBC_BACKTRACE 1
+#define USE_SYMBOL_DB 1
+#define FUNC_NAME_MAX_LEN 128
+#define FILE_LEN 255
+#define PATH_LEN (FILE_LEN + NAME_MAX)
+#define BUF_SIZE 255
+#define CALLSTACK_SIZE 100
+/* permission for open file */
+#define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+/* permission for open file */
+#define FILE_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
+
+int sig_to_handle[] = { /* SIGHUP, SIGINT, SIGQUIT, */ SIGILL, /*SIGTRAP, */
+       SIGABRT,        /*SIGIOT, */SIGBUS,
+       SIGFPE, /*SIGKILL, SIGUSR1 */ SIGSEGV,  /*SIGUSR2, */
+       SIGPIPE                 /*SIGXCPU,SIGXFSZ,,, */
+};
+#define NUM_SIG_TO_HANDLE      \
+       ((int)(sizeof(sig_to_handle)/sizeof(sig_to_handle[0])))
+
+struct sigaction g_oldact[NUM_SIG_TO_HANDLE];
+
+static char *fgets_fd(char *s, int n, int fd)
+{
+       char c;
+       register char *cs;
+       int num = 0;
+
+       cs = s;
+       while (--n > 0 && (num = read(fd, &c, 1) > 0)) {
+               if ((*cs++ = c) == '\n')
+                       break;
+       }
+       *cs = '\0';
+       return (num == 0 && cs == s) ? NULL : s;
+}
+
+/* WARNING : formatted string buffer is limited to 1024 byte */
+static int fprintf_fd(int fd, const char *fmt, ...)
+{
+       int n;
+       char buff[1024];
+       va_list args;
+
+       va_start(args, fmt);
+       n = vsnprintf(buff, 1024 - 1, fmt, args);
+       write(fd, buff, n);
+       va_end(args);
+       return n;
+}
+static char *remove_path(const char *cmd)
+{
+       char *t;
+       char *r;
+
+       t = r = (char *)cmd;
+       while (*t) {
+               if (*t == '/')
+                       r = t + 1;
+               t++;
+       }
+       return r;
+}
+
+static char *get_fpath(long *value, struct addr_node *start)
+{
+       struct addr_node *t_node;
+       struct addr_node *n_node;
+
+       if (value == 0 || start == NULL)
+               return NULL;
+       t_node = start;
+       n_node = t_node->next;
+       while (t_node) {
+               if (t_node->endaddr <= value) {
+                       /* next node */
+                       if (n_node == NULL)
+                               return NULL;
+                       t_node = n_node;
+                       n_node = n_node->next;
+               } else if (t_node->startaddr <= value)
+                       return t_node->fpath;
+               else
+                       return NULL;
+       }
+}
+
+static long *get_start_addr(long *value, struct addr_node *start)
+{
+       struct addr_node *t_node;
+       struct addr_node *n_node;
+
+       if (value == 0 || start == NULL)
+               return NULL;
+       t_node = start;
+       n_node = t_node->next;
+       while (t_node) {
+               if (t_node->endaddr <= value) {
+                       /* next node */
+                       if (n_node == NULL)
+                               return NULL;
+                       t_node = n_node;
+                       n_node = n_node->next;
+               } else if (t_node->startaddr <= value)
+                       return t_node->startaddr;
+               else
+                       return NULL;
+       }
+}
+
+#ifdef TARGET
+/* get function symbol from elf */
+static int
+trace_symbols(void *const *array, int size, struct addr_node *start, int fd_cs)
+{
+       int cnt;
+       Dl_info info_funcs;
+#ifndef USE_SYMBOL_DB
+       int i;
+       Elf32_Ehdr elf_h;
+       Elf32_Shdr *s_headers;
+       int strtab_index = 0;
+       int symtab_index = 0;
+       int num_st = 0;
+       Elf32_Sym *symtab_entry;
+       int fd;
+       int ret;
+       char filename[256];
+#endif
+       unsigned int offset_addr;
+       unsigned int start_addr;
+       unsigned int addr;
+
+       for (cnt = 0; cnt < size; cnt++) {
+#ifndef USE_SYMBOL_DB
+               num_st = 0;
+#endif
+               /* FIXME : for walking on stack trace */
+               if (dladdr(array[cnt], &info_funcs) == 0) {
+                       fprintf(stderr, "[sys-assert]dladdr returnes error!\n");
+                       /* print just address */
+                       fprintf_fd(fd_cs, "%2d: (%p)\n", cnt, array[cnt]);
+
+                       continue;
+               }
+               start_addr = (unsigned int)get_start_addr(array[cnt], start);
+               addr = (unsigned int)array[cnt];
+/* because of launchpad,
+ * return value of dladdr when find executable is wrong.
+ * so fix dli_fname here */
+               if (info_funcs.dli_fbase == (void *)0x8000
+                   &&
+                   (strncmp("/opt/apps/", info_funcs.dli_fname,
+                     strlen("/opt/apps/")) == 0)) {
+                       fprintf(stderr,
+                                       "[sys-assert][%d] fname = %s, fbase = %p, sname = %s, saddr = %p\n",
+                                       cnt, info_funcs.dli_fname,
+                                       info_funcs.dli_fbase,
+                                       info_funcs.dli_sname, info_funcs.dli_saddr);
+                       info_funcs.dli_fname = get_fpath(array[cnt], start);
+                       offset_addr = addr;
+                       fprintf(stderr,
+                                       "[sys-assert][%d] start_addr : %x, addr : %x, offset_addr : %x\n",
+                                       cnt, start_addr, addr, offset_addr);
+               } else {
+                       offset_addr = addr - start_addr;
+               }
+               if (info_funcs.dli_sname == NULL) {
+#ifndef USE_SYMBOL_DB
+/*FIXME : get dbg file name from debuglink and search dbg file in DBG_DIR */
+                       strcpy(filename, DBG_DIR);
+                       strncat(filename, info_funcs.dli_fname, 128);
+                       fd = open(filename, O_RDONLY);
+                       if (fd < 0) {
+                               fprintf_fd(fd_cs,
+                                               "%2d: (%p) [%s]+%p\n",
+                                               cnt, array[cnt],
+                                               info_funcs.dli_fname, offset_addr);
+                               continue;
+                       }
+                       ret = read(fd, &elf_h, sizeof(Elf32_Ehdr));
+                       if (ret < sizeof(Elf32_Ehdr)) {
+                               fprintf(stderr,
+                                               "[sys-assert]readnum = %d, [%s]\n",
+                                               ret, info_funcs.dli_fname);
+                               fprintf_fd(fd_cs,
+                                               "%2d: (%p) [%s]+%p\n",
+                                               cnt, array[cnt],
+                                               info_funcs.dli_fname, offset_addr);
+                               continue;
+                       }
+                       if (elf_h.e_type == ET_EXEC) {
+                               info_funcs.dli_fbase = 0;
+                               offset_addr = addr;
+                       }
+                       s_headers =
+                           (Elf32_Shdr *) mmap(0,
+                                               elf_h.e_shnum *
+                                               sizeof
+                                               (Elf32_Shdr),
+                                               PROT_READ |
+                                               PROT_WRITE,
+                                               MAP_PRIVATE |
+                                               MAP_ANONYMOUS, -1, 0);
+                       if (s_headers == NULL) {
+                               fprintf(stderr, "[sys-assert]malloc failed\n");
+                               fprintf_fd(fd_cs,
+                                               "%2d: (%p) [%s]+%p\n",
+                                               cnt, array[cnt],
+                                               info_funcs.dli_fname, offset_addr);
+                               continue;
+                       }
+                       lseek(fd, elf_h.e_shoff, SEEK_SET);
+                       if (elf_h.e_shentsize > sizeof(Elf32_Shdr))
+                               return false;
+                       for (i = 0; i < elf_h.e_shnum; i++) {
+                               ret =
+                                   read(fd, &s_headers[i], elf_h.e_shentsize);
+                               if (ret < elf_h.e_shentsize) {
+                                       fprintf(stderr,
+                                                       "[sys-assert]read error\n");
+                                       munmap(s_headers,
+                                              elf_h.e_shnum *
+                                              sizeof(Elf32_Shdr));
+                                       return false;
+                               }
+                       }
+                       for (i = 0; i < elf_h.e_shnum; i++) {
+/* find out .symtab Section index */
+                               if (s_headers[i].sh_type == SHT_SYMTAB) {
+                                       symtab_index = i;
+                                       num_st =
+                                           s_headers[i].sh_size /
+                                           s_headers[i].sh_entsize;
+/* number of .symtab entry */
+                                       break;
+                               }
+                       }
+                       /*.strtab index */
+                       strtab_index = s_headers[symtab_index].sh_link;
+                       symtab_entry =
+                           (Elf32_Sym *)mmap(0, sizeof(Elf32_Sym) * num_st,
+                                             PROT_READ | PROT_WRITE,
+                                             MAP_PRIVATE | MAP_ANONYMOUS, -1,
+                                             0);
+                       if (symtab_entry == NULL) {
+                               fprintf(stderr, "[sys-assert]malloc failed\n");
+                               munmap(s_headers,
+                                      elf_h.e_shnum * sizeof(Elf32_Shdr));
+                               return false;
+                       }
+                       lseek(fd, s_headers[symtab_index].sh_offset, SEEK_SET);
+                       for (i = 0; i < num_st; i++) {
+                               ret =
+                                   read(fd, &symtab_entry[i],
+                                        sizeof(Elf32_Sym));
+                               if (ret < sizeof(Elf32_Sym)) {
+                                       fprintf(stderr,
+                                                       "[sys-assert]symtab_entry[%d],\
+                                                       num_st=%d, readnum = %d\n",
+                                                       i, num_st, ret);
+                                       break;
+                               }
+                               if (((info_funcs.dli_fbase +
+                                     symtab_entry[i].st_value)
+                                    <= array[cnt])
+                                   && (array[cnt] <=
+                                       (info_funcs.dli_fbase +
+                                        symtab_entry
+                                        [i].st_value +
+                                        symtab_entry[i].st_size))) {
+                                       if (symtab_entry[i].st_shndx !=
+                                           STN_UNDEF) {
+                                               lseek(fd,
+                                                     s_headers
+                                                     [strtab_index].sh_offset +
+                                                     symtab_entry[i].st_name,
+                                                     SEEK_SET);
+                                               info_funcs.dli_sname = (void *)
+                                                   mmap(0,
+                                                        FUNC_NAME_MAX_LEN,
+                                                        PROT_READ
+                                                        |
+                                                        PROT_WRITE,
+                                                        MAP_PRIVATE
+                                                        |
+                                                        MAP_ANONYMOUS, -1, 0);
+                                               ret =
+                                                   read(fd,
+                                                        info_funcs.dli_sname,
+                                                        FUNC_NAME_MAX_LEN);
+                                               info_funcs.dli_saddr =
+                                                   info_funcs.dli_fbase +
+                                                   symtab_entry[i].st_value;
+                                       }
+                                       break;
+                               }
+                       }
+                       munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr));
+                       munmap(symtab_entry, sizeof(Elf32_Sym) * num_st);
+                       close(fd);
+#endif
+                       fprintf_fd(fd_cs, "%2d: (%p) [%s]+%p\n",
+                                  cnt, array[cnt],
+                                  info_funcs.dli_fname, offset_addr);
+               } else {
+
+                       if (array[cnt] >= info_funcs.dli_saddr) {
+                               fprintf_fd(fd_cs,
+                                          "%2d: %s+0x%x(%p) [%s]+%p\n",
+                                          cnt,
+                                          info_funcs.dli_sname,
+                                          (array[cnt] -
+                                           info_funcs.dli_saddr),
+                                          array[cnt],
+                                          info_funcs.dli_fname, offset_addr);
+                       } else {
+                               fprintf_fd(fd_cs,
+                                          "%2d: %s-0x%x(%p) [%s]+%p\n",
+                                          cnt,
+                                          info_funcs.dli_sname,
+                                          (info_funcs.dli_saddr
+                                           - array[cnt]),
+                                          array[cnt],
+                                          info_funcs.dli_fname, offset_addr);
+                       }
+               }
+       }
+       return true;
+}
+#endif
+/* get address list from maps  with print to file */
+static struct addr_node *get_addr_list_from_maps_with_print(int fd_maps, int fd)
+{
+       int result;
+       char linebuf[BUF_SIZE];
+       char addr[20];
+       char perm[5];
+       char path[PATH_LEN];
+       long *saddr;
+       long *eaddr;
+       int fpath_len;
+       struct addr_node *head = NULL;
+       struct addr_node *tail = NULL;
+       struct addr_node *t_node = NULL;
+
+       fprintf_fd(fd, "\n%s\n", CRASH_MAPSINFO_TITLE);
+
+/* parsing the maps to get executable code address */
+       while (fgets_fd(linebuf, BUF_SIZE, fd_maps) != NULL) {
+               memset(path, 0, PATH_LEN);
+               result =
+                   sscanf(linebuf, "%s %s %*s %*s %*s %s ", addr, perm, path);
+               perm[4] = 0;
+/*if perm[2]=='x',addr is valid value so we have to store the address */
+#ifdef TARGET
+               if ((perm[2] == 'x' && path[0] == '/')
+                               || (perm[1] == 'w' && path[0] != '/'))
+#else
+               if (strncmp(perm, "r-xp", 4) == 0)
+#endif
+               {
+                       /* add addr node to list */
+                       addr[8] = 0;
+                       saddr = (long *)strtoul(addr, NULL, 16);
+                       eaddr = (long *)strtoul(&addr[9], NULL, 16);
+                       /* make node and attach to the list */
+                       t_node =
+                           (struct addr_node *)mmap(0,
+                                                    sizeof
+                                                    (struct
+                                                     addr_node),
+                                                    PROT_READ |
+                                                    PROT_WRITE,
+                                                    MAP_PRIVATE
+                                                    | MAP_ANONYMOUS, -1, 0);
+                       if (t_node == NULL) {
+                               fprintf(stderr, "error : mmap\n");
+                               return NULL;
+                       }
+                       memcpy(t_node->perm, perm, 5);
+                       t_node->startaddr = saddr;
+                       t_node->endaddr = eaddr;
+                       t_node->fpath = NULL;
+                       fpath_len = strlen(path);
+                       if (fpath_len > 0) {
+                               t_node->fpath =
+                                   (char *)mmap(0,
+                                                fpath_len + 1,
+                                                PROT_READ |
+                                                PROT_WRITE,
+                                                MAP_PRIVATE |
+                                                MAP_ANONYMOUS, -1, 0);
+                               memset(t_node->fpath, 0, fpath_len + 1);
+                               memcpy(t_node->fpath, path, fpath_len);
+                               fprintf_fd(fd, "%08x %08x %s %s\n",
+                                               (unsigned int)t_node->startaddr,
+                                               (unsigned int)t_node->endaddr,
+                                               t_node->perm, t_node->fpath);
+                       } else {
+                               t_node->fpath =
+                                   (char *)mmap(0, 8,
+                                                PROT_READ |
+                                                PROT_WRITE,
+                                                MAP_PRIVATE |
+                                                MAP_ANONYMOUS, -1, 0);
+                               memset(t_node->fpath, 0, 8);
+                               memcpy(t_node->fpath, "[anony]", 7);
+                       }
+                       t_node->next = NULL;
+                       if (head == NULL) {
+                               head = t_node;
+                               tail = t_node;
+                       } else {
+                               tail->next = t_node;
+                               tail = t_node;
+                       }
+               }
+       }
+       fprintf_fd(fd, "%s\n", CRASH_MAPSINFO_TITLE_E);
+       return head;
+}
+/* get address list from maps */
+static struct addr_node *get_addr_list_from_maps(int fd_maps)
+{
+       int result;
+       char linebuf[BUF_SIZE];
+       char addr[20];
+       char perm[5];
+       char path[PATH_LEN];
+       long *saddr;
+       long *eaddr;
+       int fpath_len;
+       struct addr_node *head = NULL;
+       struct addr_node *tail = NULL;
+       struct addr_node *t_node = NULL;
+
+/* parsing the maps to get executable code address */
+       while (fgets_fd(linebuf, BUF_SIZE, fd_maps) != NULL) {
+               memset(path, 0, PATH_LEN);
+               result =
+                   sscanf(linebuf, "%s %s %*s %*s %*s %s ", addr, perm, path);
+               perm[4] = 0;
+/*if perm[2]=='x',addr is valid value so we have to store the address */
+#ifdef TARGET
+               if ((perm[2] == 'x' && path[0] == '/')
+                               || (perm[1] == 'w' && path[0] != '/'))
+#else
+               if (strncmp(perm, "r-xp", 4) == 0)
+#endif
+               {
+                       /* add addr node to list */
+                       addr[8] = 0;
+                       saddr = (long *)strtoul(addr, NULL, 16);
+                       eaddr = (long *)strtoul(&addr[9], NULL, 16);
+                       /* make node and attach to the list */
+                       t_node =
+                           (struct addr_node *)mmap(0,
+                                                    sizeof
+                                                    (struct
+                                                     addr_node),
+                                                    PROT_READ |
+                                                    PROT_WRITE,
+                                                    MAP_PRIVATE
+                                                    | MAP_ANONYMOUS, -1, 0);
+                       if (t_node == NULL) {
+                               fprintf(stderr, "error : mmap\n");
+                               return NULL;
+                       }
+                       memcpy(t_node->perm, perm, 5);
+                       t_node->startaddr = saddr;
+                       t_node->endaddr = eaddr;
+                       t_node->fpath = NULL;
+                       fpath_len = strlen(path);
+                       if (fpath_len > 0) {
+                               t_node->fpath =
+                                   (char *)mmap(0,
+                                                fpath_len + 1,
+                                                PROT_READ |
+                                                PROT_WRITE,
+                                                MAP_PRIVATE |
+                                                MAP_ANONYMOUS, -1, 0);
+                               memset(t_node->fpath, 0, fpath_len + 1);
+                               memcpy(t_node->fpath, path, fpath_len);
+                       } else {
+                               t_node->fpath =
+                                   (char *)mmap(0, 8,
+                                                PROT_READ |
+                                                PROT_WRITE,
+                                                MAP_PRIVATE |
+                                                MAP_ANONYMOUS, -1, 0);
+                               memset(t_node->fpath, 0, 8);
+                               memcpy(t_node->fpath, "[anony]", 7);
+                       }
+
+                       t_node->next = NULL;
+                       if (head == NULL) {
+                               head = t_node;
+                               tail = t_node;
+                       } else {
+                               tail->next = t_node;
+                               tail = t_node;
+                       }
+               }
+       }
+       return head;
+}
+
+static void print_node_to_file(struct addr_node *start, int fd)
+{
+       struct addr_node *t_node;
+
+       t_node = start;
+       fprintf(stderr, "[sys-assert]start print_node_to_file\n");
+       fprintf_fd(fd, "\n%s\n", CRASH_MAPSINFO_TITLE);
+       while (t_node) {
+               if (!strncmp("[anony]", t_node->fpath, strlen("[anony]"))) {
+                       t_node = t_node->next;
+               } else {
+                       fprintf_fd(fd, "%08x %08x %s %s\n",
+                               (unsigned int)t_node->startaddr,
+                               (unsigned int)t_node->endaddr,
+                               t_node->perm, t_node->fpath);
+                       t_node = t_node->next;
+               }
+       }
+       fprintf_fd(fd, "%s\n", CRASH_MAPSINFO_TITLE_E);
+}
+
+static void free_all_nodes(struct addr_node *start)
+{
+       struct addr_node *t_node, *n_node;
+       int fpath_len;
+
+       if (start == NULL)
+               return;
+       t_node = start;
+       n_node = t_node->next;
+       while (t_node) {
+               if (t_node->fpath != NULL) {
+                       fpath_len = strlen(t_node->fpath);
+                       munmap(t_node->fpath, fpath_len + 1);
+               }
+               munmap(t_node, sizeof(struct addr_node));
+               if (n_node == NULL)
+                       break;
+               t_node = n_node;
+               n_node = n_node->next;
+       }
+}
+
+static void print_signal_info(const siginfo_t *info, int fd)
+{
+       int signum = info->si_signo;
+
+       fprintf_fd(fd, "Signal: %d\n", signum);
+       switch (signum) {
+       case SIGINT:
+               fprintf_fd(fd, "      (SIGINT)\n");
+               break;
+       case SIGILL:
+               fprintf_fd(fd, "      (SIGILL)\n");
+               break;
+       case SIGABRT:
+               fprintf_fd(fd, "      (SIGABRT)\n");
+               break;
+       case SIGBUS:
+               fprintf_fd(fd, "      (SIGBUS)\n");
+               break;
+       case SIGFPE:
+               fprintf_fd(fd, "      (SIGFPE)\n");
+               break;
+       case SIGKILL:
+               fprintf_fd(fd, "      (SIGKILL)\n");
+               break;
+       case SIGSEGV:
+               fprintf_fd(fd, "      (SIGSEGV)\n");
+               break;
+       case SIGPIPE:
+               fprintf_fd(fd, "      (SIGPIPE)\n");
+               break;
+       default:
+               fprintf_fd(fd, "\n");
+       }
+       /* print signal si_code info */
+       fprintf_fd(fd, "      si_code: %d\n", info->si_code);
+       if (info->si_code <= 0 || info->si_code >= 0x80) {
+               switch (info->si_code) {
+#ifdef SI_TKILL
+               case SI_TKILL:
+                       /* FIXME : print exe name displace with info->si_pid */
+                       fprintf_fd(fd,
+                                  "      signal sent by tkill (sent by pid %d, uid %d)\n",
+                                  info->si_pid, info->si_uid);
+                       fprintf_fd(fd, "      TIMER: %d\n", SI_TIMER);
+                       break;
+#endif
+#ifdef SI_USER
+               case SI_USER:
+                       /* FIXME : print exe name displace with info->si_pid */
+                       fprintf_fd(fd,
+                                  "      signal sent by kill (sent by pid %d, uid %d)\n",
+                                  info->si_pid, info->si_uid);
+                       break;
+#endif
+#ifdef SI_KERNEL
+               case SI_KERNEL:
+                       fprintf_fd(fd, "      signal sent by the kernel\n");
+                       break;
+#endif
+               }
+
+       } else if (signum == SIGILL) {
+               switch (info->si_code) {
+               case ILL_ILLOPC:
+                       fprintf_fd(fd, "      illegal opcode\n");
+                       break;
+               case ILL_ILLOPN:
+                       fprintf_fd(fd, "      illegal operand\n");
+                       break;
+               case ILL_ILLADR:
+                       fprintf_fd(fd, "      illegal addressing mode\n");
+                       break;
+               case ILL_ILLTRP:
+                       fprintf_fd(fd, "      illegal trap\n");
+                       break;
+               case ILL_PRVOPC:
+                       fprintf_fd(fd, "      privileged opcode\n");
+                       break;
+               case ILL_PRVREG:
+                       fprintf_fd(fd, "      privileged register\n");
+                       break;
+               case ILL_COPROC:
+                       fprintf_fd(fd, "      coprocessor error\n");
+                       break;
+               case ILL_BADSTK:
+                       fprintf_fd(fd, "      internal stack error\n");
+                       break;
+               default:
+                       fprintf_fd(fd, "      illegal si_code = %d\n", info->si_code);
+                       break;
+               }
+               fprintf_fd(fd, "      si_addr: %p\n", info->si_addr);
+       } else if (signum == SIGFPE) {
+               switch (info->si_code) {
+               case FPE_INTDIV:
+                       fprintf_fd(fd, "      integer divide by zero\n");
+                       break;
+               case FPE_INTOVF:
+                       fprintf_fd(fd, "      integer overflow\n");
+                       break;
+               case FPE_FLTDIV:
+                       fprintf_fd(fd, "      floating-point divide by zero\n");
+                       break;
+               case FPE_FLTOVF:
+                       fprintf_fd(fd, "      floating-point overflow\n");
+                       break;
+               case FPE_FLTUND:
+                       fprintf_fd(fd, "      floating-point underflow\n");
+                       break;
+               case FPE_FLTRES:
+                       fprintf_fd(fd, "      floating-point inexact result\n");
+                       break;
+               case FPE_FLTINV:
+                       fprintf_fd(fd, "      invalid floating-point operation\n");
+                       break;
+               case FPE_FLTSUB:
+                       fprintf_fd(fd, "      subscript out of range\n");
+                       break;
+               default:
+                       fprintf_fd(fd, "      illegal si_code: %d\n", info->si_code);
+                       break;
+               }
+       } else if (signum == SIGSEGV) {
+               switch (info->si_code) {
+               case SEGV_MAPERR:
+                       fprintf_fd(fd, "      address not mapped to object\n");
+                       break;
+               case SEGV_ACCERR:
+                       fprintf_fd(fd,
+                                  "      invalid permissions for mapped object\n");
+                       break;
+               default:
+                       fprintf_fd(fd, "      illegal si_code: %d\n", info->si_code);
+                       break;
+               }
+               fprintf_fd(fd, "      si_addr = %p\n", info->si_addr);
+       } else if (signum == SIGBUS) {
+               switch (info->si_code) {
+               case BUS_ADRALN:
+                       fprintf_fd(fd, "      invalid address alignment\n");
+                       break;
+               case BUS_ADRERR:
+                       fprintf_fd(fd, "      nonexistent physical address\n");
+                       break;
+               case BUS_OBJERR:
+                       fprintf_fd(fd, "      object-specific hardware error\n");
+                       break;
+               default:
+                       fprintf_fd(fd, "      illegal si_code: %d\n", info->si_code);
+                       break;
+               }
+               fprintf_fd(fd, "      si_addr: %p\n", info->si_addr);
+
+       }
+}
+
+
+#define VIP_PATH               "/tmp/vip"
+#define PERMANENT_PATH "/tmp/permanent"
+
+static int check_redscreen(int pid)
+{
+       DIR *dp;
+       struct dirent *dirp;
+       char pid_str[10];
+
+       snprintf(pid_str, 10, "%d", pid);
+       if ((dp = opendir(VIP_PATH)) == NULL) {
+               return 0;
+       } else {
+               while ((dirp = readdir(dp)) != NULL) {
+                       if (strcmp(dirp->d_name, pid_str) == 0) {
+                               fprintf(stderr, "pid=%d is VIP process\n", pid);
+                               closedir(dp);
+                               return 1;
+                       }
+               }
+       }
+       closedir(dp);
+       if ((dp = opendir(PERMANENT_PATH)) == NULL) {
+               return 0;
+       } else {
+               while ((dirp = readdir(dp)) != NULL) {
+                       if (strcmp(dirp->d_name, pid_str) == 0) {
+                               fprintf(stderr,
+                                       "pid=%d is Permanent process\n", pid);
+                               closedir(dp);
+                               return 1;
+                       }
+               }
+       }
+       closedir(dp);
+       return 0;
+}
+/*localtime() can not use in signal handler,
+so we need signal safe version of localtime */
+static inline void get_localtime(time_t cur_time, struct tm *ctime)
+{
+       int tday[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+       int time_var = cur_time;
+       int i = 0;
+
+       ctime->tm_sec = time_var % 60;
+       time_var /= 60;
+       ctime->tm_min = time_var % 60;
+       time_var /= 60;
+       /* do we need to fix up timze zone ? */
+       ctime->tm_hour = time_var % 24;
+       time_var /= 24;
+       int year = 1970;
+       int leak_year = 0;
+       while (time_var > 365 + (leak_year = (((year % 4) == 0)
+                                       && ((year % 100) != 0))
+                               || ((year % 400) == 0))) {
+               time_var = time_var - 365 - leak_year;
+               year++;
+       }
+       ctime->tm_year = year;
+       leak_year = (((year % 4) == 0) && ((year % 100) != 0))
+           || ((year % 400) == 0);
+       time_var++;
+       while (time_var > tday[i]) {
+               time_var -= tday[i];
+               if (i == 1)
+                       time_var -= leak_year;
+               i++;
+       }
+       ctime->tm_mon = ++i;
+       ctime->tm_mday = time_var;
+       fprintf(stderr, "local time %d %d %d %d:%d:%d\n",
+                       ctime->tm_year, ctime->tm_mon, ctime->tm_mday,
+                       ctime->tm_hour, ctime->tm_min, ctime->tm_sec);
+}
+void sighandler(int signum, siginfo_t *info, void *context)
+{
+       /* for context info */
+       ucontext_t *ucontext = context;
+       void *callstack_addrs[CALLSTACK_SIZE];
+       int cnt_callstack = 0;
+       /* for backtrace_symbols() */
+       char **callstack_strings;
+       struct addr_node *head = NULL;
+       int i;
+       /* file descriptor */
+       int fd_cs;              /* for cs file */
+       int fd_maps;            /* for maps */
+       int fd_meminfo;         /* for meminfo */
+#ifdef STANDALONE
+       int fd_verinfo;         /* for version info */
+#endif
+       int fd_cmdline;         /* for cmdline */
+       int fd_status;          /* for status */
+       int fd_curbs;           /* for inotify */
+       pid_t cs_pid;
+       pid_t cs_tid;
+       char cs_timestr[64];
+       char cs_processname[NAME_MAX] = {0,};
+       char cs_exepath[PATH_LEN] = {0,};
+       char cs_filepath[PATH_LEN];
+       /* for get time  */
+       time_t cur_time;
+#ifdef STANDALONE
+       struct tm ctime;
+       char timestr[64];
+#endif
+       /* for get info */
+       int thread_use;
+       char *p_exepath = NULL;
+       char tag[64];
+       char infoname[20];
+       char memsize1[24];
+       char linebuf[BUF_SIZE];
+
+       cur_time = time(NULL);
+#ifdef STANDALONE
+       gmtime_r(&cur_time, &ctime);
+       /*localtime_r(&cur_time, &ctime);*/
+       /*get_localtime(cur_time, &ctime);*/
+#endif
+       fprintf(stderr, "[sys_assert]START of sighandler\n");
+       /* get pid */
+       cs_pid = getpid();
+       cs_tid = (long int)syscall(__NR_gettid);
+#ifdef TARGET
+       /* open maps file */
+       if ((fd_maps = open(MAPS_PATH, O_RDONLY)) < 0) {
+               fprintf(stderr, "[sys-assert]can't open %s\n", MAPS_PATH);
+       } else {
+               /* parsing the maps to get code segment address*/
+               head = get_addr_list_from_maps(fd_maps);
+               close(fd_maps);
+       }
+       if (head == NULL) {
+               fprintf(stderr, ">>>>error : cannot get address list from maps\n");
+       } else {
+#ifndef SUPPORT_LIBC_BACKTRACE
+               /* backtrace using fp */
+               long *SP;       /* point to the top of stack */
+               long *PC;       /* point to the program counter */
+               long *BP = __libc_stack_end;
+               long *FP;
+               long *framep;
+               /* get sp , pc and bp */
+               SP = (long *)ucontext->uc_mcontext.arm_sp;
+               PC = (long *)ucontext->uc_mcontext.arm_pc;
+               FP = (long *)ucontext->uc_mcontext.arm_fp;
+               framep = (long *)FP;
+               callstack_addrs[cnt_callstack++] =
+                       (long *)ucontext->uc_mcontext.arm_pc;
+               if (FP != NULL) {
+                       for (; framep < BP;) {
+                               if (is_valid_addr(framep, head) == false)
+                                       break;
+
+                               if (is_valid_addr((long *)*framep, head) == false)
+                                       break;
+
+                               callstack_addrs[cnt_callstack] = (long *)*framep;
+
+                               framep--;
+                               framep = (long *)(*framep);
+                               cnt_callstack++;
+
+                               if (cnt_callstack == CALLSTACK_SIZE)
+                                       break;
+                               if (framep < FP)
+                                       break;
+                       }
+               }
+#else          /*SUPPORT_LIBC_BACKTRACE*/
+               cnt_callstack = backtrace(callstack_addrs, CALLSTACK_SIZE);
+               if (cnt_callstack > 2) {
+                       cnt_callstack -= 2;
+               } else {
+                       callstack_addrs[2] = (long *)ucontext->uc_mcontext.arm_pc;
+                       callstack_addrs[3] = (long *)ucontext->uc_mcontext.arm_lr;
+                       cnt_callstack = 2;
+               }
+#endif
+       }
+#else          /* i386 */
+       layout *ebp = ucontext->uc_mcontext.gregs[REG_EBP];
+       callstack_addrs[cnt_callstack++] =
+               (long *)ucontext->uc_mcontext.gregs[REG_EIP];
+       while (ebp) {
+               callstack_addrs[cnt_callstack++] = ebp->ret;
+               ebp = ebp->ebp;
+       }
+       callstack_strings = backtrace_symbols(callstack_addrs, cnt_callstack);
+#endif
+       /* get exepath */
+       if ((fd_cmdline = open(CMDLINE_PATH, O_RDONLY)) < 0) {
+               fprintf(stderr, "[sys-assert]can't open %s\n", CMDLINE_PATH);
+               return;
+       } else {
+               i = read(fd_cmdline, cs_exepath, sizeof(cs_exepath));
+               close(fd_cmdline);
+               if (i <= 0) {
+                       fprintf(stderr, "[sys-assert]can't get cmdline\n");
+                       return;
+               } else {
+                       cs_exepath[i] = '\0';
+                       fprintf(stderr, "[sys-assert]exepath = %s\n", cs_exepath);
+               }
+       }
+       /* get processname */
+       if ((fd_status = open(STATUS_PATH, O_RDONLY)) < 0) {
+               fprintf(stderr, "[sys-assert]can't open %s\n", STATUS_PATH);
+               return;
+       } else {
+               i = read(fd_status, linebuf, sizeof(linebuf));
+               close(fd_status);
+               if (i <= 0) {
+                       fprintf(stderr, "[sys-assert]can't get status\n");
+                       cs_processname[0] = '\0';
+               } else
+                       sscanf(linebuf, "%s %s", tag, cs_processname);
+
+               if (cs_processname[0] == '\0') {
+                       p_exepath = remove_path(cs_exepath);
+                       if (p_exepath == NULL)
+                               return;
+                       snprintf(cs_processname, NAME_MAX, "%s", p_exepath);
+               }
+               fprintf(stderr, "[sys-assert]processname = %s\n", cs_processname);
+       }
+       /* added temporary skip  when crash-worker is asserted */
+       if (!strcmp(cs_processname, "crash-worker") || !strcmp(cs_processname, "crash-popup"))
+               return;
+       /* thread check */
+       if (cs_pid == cs_tid) {
+               thread_use = false;
+               fprintf(stderr,
+                               "[sys_assert]this thread is main thread. pid=%d\n",
+                               cs_pid);
+       } else {
+               thread_use = true;
+               fprintf(stderr,
+                               "[sys_assert]this process is multi-thread process.\
+                               pid=%d, tid=%d\n", cs_pid, cs_tid);
+       }
+       /* make crash info file name */
+#ifdef STANDALONE
+       strftime(cs_timestr, sizeof(cs_timestr), "%Y%m%d%H%M%S", &ctime);
+       if (snprintf(cs_filepath, PATH_LEN,
+                               "%s/%s_%s.cs", CRASH_REPORT_PATH, cs_processname, cs_timestr) == 0) {
+               fprintf(stderr,
+                               "[sys-assert]can't make crash info file name : %s%s\n",
+                               cs_processname, cs_timestr);
+               return;
+       }
+       /* check crash info dump directory, make directory if absent */
+       if (access(CRASH_REPORT_PATH, F_OK) == -1) {
+               if (mkdir(CRASH_REPORT_PATH, DIR_PERMS) < 0) {
+                       fprintf(stderr,
+                                       "[sys-assert]can't make dir : %s errno : %s\n",
+                                       CRASH_REPORT_PATH, strerror(errno));
+                       return;
+               }
+       }
+#else
+       snprintf(cs_timestr, sizeof(cs_timestr), "%lu", cur_time);
+       fprintf(stderr, "[sys-assert]cs timestr %s\n",cs_timestr);
+       if (snprintf(cs_filepath, PATH_LEN,
+                               "%s/%d_%s.info", CRASH_INFO_PATH, cs_pid, cs_timestr) == 0) {
+               fprintf(stderr,
+                               "[sys-assert]can't make crash info file name : %d%s\n",
+                               cs_pid, cs_timestr);
+               return;
+       }
+       /* check crash info dump directory, make directory if absent */
+       if (access(CRASH_INFO_PATH, F_OK) == -1) {
+               if (mkdir(CRASH_INFO_PATH, DIR_PERMS) < 0) {
+                       fprintf(stderr,
+                                       "[sys-assert]can't make dir : %s errno : %s\n",
+                                       CRASH_INFO_PATH, strerror(errno));
+                       return;
+               }
+       }
+#endif
+       /* logging crash information to syslog */
+       syslog(LOG_ERR, "crashed [%s] processname=%s, pid=%d, tid=%d, signal=%d",
+                       cs_timestr, cs_processname, cs_pid, cs_tid, info->si_signo);
+       /* complete filepath_cs */
+       if (!strlen(cs_filepath))
+               return;
+       /* create cs file */
+       if ((fd_cs = creat(cs_filepath, FILE_PERMS)) < 0) {
+               fprintf(stderr,
+                               "[sys-assert]can't create %s. errno = %s\n",
+                               cs_filepath, strerror(errno));
+               return;
+       }
+#ifdef STANDALONE
+       /* print version info */
+       fprintf_fd(fd_cs, "S/W Version Information\n");
+       if ((fd_verinfo = open(VERINFO_PATH, O_RDONLY)) < 0) {
+               fprintf(stderr, "[sys-assert]can't open %s\n", VERINFO_PATH);
+       } else {
+               while (fgets_fd(linebuf, BUF_SIZE, fd_verinfo) != NULL) {
+                       if (strncmp("Major=", linebuf, 6) == 0) {
+                               fprintf_fd(fd_cs, "%s", linebuf);
+                       } else if (strncmp("Minor=", linebuf, 6) == 0) {
+                               fprintf_fd(fd_cs, "%s", linebuf);
+                       } else if (strncmp("Build=", linebuf, 6) == 0) {
+                               fprintf_fd(fd_cs, "%s", linebuf);
+                       } else if (strncmp("Date=", linebuf, 5) == 0) {
+                               fprintf_fd(fd_cs, "%s", linebuf);
+                       } else if (strncmp("Time=", linebuf, 5) == 0) {
+                               fprintf_fd(fd_cs, "%s", linebuf);
+                               break;
+                       }
+               }
+               close(fd_verinfo);
+       }
+       /* print app info */
+       fprintf_fd(fd_cs, "Process Name: %s\n", cs_processname);
+       fprintf_fd(fd_cs, "PID: %d\n", cs_pid);
+       /* print time  */
+       /*localtime_r(&cur_time, &ctime);*/
+       strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &ctime);
+       fprintf_fd(fd_cs, "Date: %s ( UTC )\n", timestr);
+       /* print exe path */
+       fprintf_fd(fd_cs, "Executable File Path: %s\n", cs_exepath);
+       fprintf(stderr, "[sys assert]Exe Path: %s\n", cs_exepath);
+#endif
+       /* print thread info */
+       if (thread_use == true) {
+               fprintf_fd(fd_cs,
+                               "This process is multi-thread process\npid=%d tid=%d\n",
+                               cs_pid, cs_tid);
+       }
+       /* print signal info */
+       print_signal_info(info, fd_cs);
+       fsync(fd_cs);
+       /* print additional info */
+#ifdef TARGET
+       fprintf_fd(fd_cs, "\n%s\n", CRASH_REGISTERINFO_TITLE);
+       fprintf_fd(fd_cs,
+                       "r0 = 0x%08x, r1 = 0x%08x\nr2 = 0x%08x, r3 = 0x%08x\n",
+                       ucontext->uc_mcontext.arm_r0,
+                       ucontext->uc_mcontext.arm_r1,
+                       ucontext->uc_mcontext.arm_r2, ucontext->uc_mcontext.arm_r3);
+       fprintf_fd(fd_cs,
+                       "r4 = 0x%08x, r5 = 0x%08x\nr6 = 0x%08x, r7 = 0x%08x\n",
+                       ucontext->uc_mcontext.arm_r4,
+                       ucontext->uc_mcontext.arm_r5,
+                       ucontext->uc_mcontext.arm_r6, ucontext->uc_mcontext.arm_r7);
+       fprintf_fd(fd_cs,
+                       "r8 = 0x%08x, r9 = 0x%08x\nr10 = 0x%08x, fp = 0x%08x\n",
+                       ucontext->uc_mcontext.arm_r8,
+                       ucontext->uc_mcontext.arm_r9,
+                       ucontext->uc_mcontext.arm_r10, ucontext->uc_mcontext.arm_fp);
+       fprintf_fd(fd_cs,
+                       "ip = 0x%08x, sp = 0x%08x\nlr = 0x%08x, pc = 0x%08x\n",
+                       ucontext->uc_mcontext.arm_ip,
+                       ucontext->uc_mcontext.arm_sp,
+                       ucontext->uc_mcontext.arm_lr, ucontext->uc_mcontext.arm_pc);
+       fprintf_fd(fd_cs, "cpsr = 0x%08x\n", ucontext->uc_mcontext.arm_cpsr);
+#endif
+       /* print meminfo */
+       fprintf_fd(fd_cs, "\n%s\n", CRASH_MEMINFO_TITLE);
+       if ((fd_meminfo = open(MEMINFO_PATH, O_RDONLY)) < 0) {
+               fprintf(stderr, "[sys-assert]can't open %s\n", MEMINFO_PATH);
+       } else {
+               while (fgets_fd(linebuf, BUF_SIZE, fd_meminfo) != NULL) {
+                       sscanf(linebuf, "%s %s %*s", infoname, memsize1);
+                       if (strcmp("MemTotal:", infoname) == 0) {
+                               fprintf_fd(fd_cs, "%s %s KB\n", infoname,
+                                               memsize1);
+                       } else if (strcmp("MemFree:", infoname) == 0) {
+                               fprintf_fd(fd_cs, "%s %s KB\n", infoname,
+                                               memsize1);
+                       } else if (strcmp("Buffers:", infoname) == 0) {
+                               fprintf_fd(fd_cs, "%s  %s KB\n",
+                                               infoname, memsize1);
+                       } else if (strcmp("Cached:", infoname) == 0) {
+                               fprintf_fd(fd_cs, "%s   %s KB\n",
+                                               infoname, memsize1);
+                               break;
+                       }
+               }
+               close(fd_meminfo);
+       }
+#ifdef TARGET
+       if (head == NULL) {
+               fprintf_fd(fd_cs, "Failed to get address list\n");
+               fprintf(stderr, ">>>>error : cannot get address list from maps\n");
+       } else {
+               /* print maps information */
+               print_node_to_file(head, fd_cs);
+               fprintf_fd(fd_cs, "\n%s (PID:%d)\n", CRASH_CALLSTACKINFO_TITLE, cs_pid);
+#ifndef SUPPORT_LIBC_BACKTRACE
+               fprintf_fd(fd_cs, "Call Stack Count: %d\n", cnt_callstack);
+               /* print callstack */
+               if (false ==
+                               trace_symbols(callstack_addrs, cnt_callstack, head, fd_cs)) {
+                       callstack_strings =
+                               backtrace_symbols(callstack_addrs, cnt_callstack);
+                       /* print callstack information */
+                       for (i = 0; i < cnt_callstack; i++)
+                               fprintf_fd(fd_cs, "%2d: %s\n", i, callstack_strings[i]);
+               }
+               if (FP == NULL)
+                       fprintf_fd(fd_cs,
+                                       "there is no callstack because of fp == NULL\n");
+#else          /*SUPPORT_LIBC_BACKTRACE*/
+               fprintf_fd(fd_cs, "Call Stack Count: %d\n", cnt_callstack);
+               /* print callstack */
+               if (false ==
+                               trace_symbols(&callstack_addrs[2], cnt_callstack, head, fd_cs)) {
+                       fprintf(stderr, "[sys-assert] trace_symbols failed\n");
+               }
+#endif
+               fprintf_fd(fd_cs, "%s\n", CRASH_CALLSTACKINFO_TITLE_E);
+               free_all_nodes(head);
+       }
+#else          /* i386 */
+       fprintf_fd(fd_cs, "\n%s (PID:%d)\n", CRASH_CALLSTACKINFO_TITLE, cs_pid);
+       fprintf_fd(fd_cs, "Call Stack Count: %d\n", cnt_callstack);
+       /* print callstack information */
+       for (i = 0; i < cnt_callstack; i++)
+               fprintf_fd(fd_cs, "%2d: %s\n", i, callstack_strings[i]);
+       fprintf_fd(fd_cs, "%s\n", CRASH_CALLSTACKINFO_TITLE_E);
+#endif
+       /* cs file sync */
+       fsync(fd_cs);
+       /* clean up */
+       if (close(fd_cs) == -1)
+               fprintf(stderr, "[sys-assert] fd_cs close error!!\n");
+#ifndef STANDALONE
+       /* core dump set */
+       if (prctl(PR_GET_DUMPABLE) == 0) {
+               fprintf(stderr, "[sys-assert]set PR_SET_DUMPABLE to 1\n");
+               prctl(PR_SET_DUMPABLE, 1);
+       }
+       /* NOTIFY CRASH */
+       if ((fd_curbs = open(CRASH_NOTI_PATH, O_RDWR | O_APPEND)) < 0) {
+               fprintf(stderr, "[sys-assert]cannot make %s !\n", CRASH_NOTI_PATH);
+       } else {
+               fprintf_fd(fd_curbs, "S|%s|%s|%d|%s|%d\n",
+                               cs_processname, cs_timestr, cs_pid, cs_exepath,
+                               strlen(cs_processname) + strlen(cs_exepath));
+               close(fd_curbs);
+       }
+#endif
+       for (i = 0; i < NUM_SIG_TO_HANDLE; i++) {
+               if (sig_to_handle[i] == signum) {
+                       sigaction(signum, &g_oldact[i], NULL);
+                       fprintf(stderr,
+                                       "sighandler = %p, g_sig_oldact[i] = %p\n",
+                                       (void *)sighandler, g_oldact[i].sa_handler);
+                       break;
+               }
+       }
+       raise(signum);
+       fprintf(stderr, "[sys_assert]END of sighandler\n");
+}
+__attribute__ ((constructor))
+void init()
+{
+       int i;
+
+       for (i = 0; i < NUM_SIG_TO_HANDLE; i++) {
+               struct sigaction act;
+               act.sa_sigaction = (void *)sighandler;
+               sigemptyset(&act.sa_mask);
+               act.sa_flags = SA_SIGINFO;
+               act.sa_flags |= SA_RESETHAND;
+               if (sigaction(sig_to_handle[i], &act, &g_oldact[i]) < 0) {
+                       perror("[sys-assert]could not set signal handler ");
+                       continue;
+               }
+       }
+}
diff --git a/sys-assert/src/sys-assert.h b/sys-assert/src/sys-assert.h
new file mode 100755 (executable)
index 0000000..1b64f6d
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * SYS-ASSERT
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _DEBUG_ASSERT_H_
+#define _DEBUG_ASSERT_H_
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+       struct addr_node {
+               long *startaddr;
+               long *endaddr;
+               char perm[5];
+               char *fpath;
+               struct addr_node *next;
+       };
+
+#ifdef __arm__
+       typedef struct layout {
+               struct layout *fp;
+               void *ret;
+       } layout;
+
+#else
+       typedef struct layout {
+               struct layout *ebp;
+               void *ret;
+       } layout;
+#endif
+
+       extern void *__libc_stack_end;
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* _DEBUG_ASSERT_H_ */