From 93a7b84b260fa6f2ea69cba3d31aed0aa3873ba3 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Fri, 4 Nov 2016 17:05:52 +0900 Subject: [PATCH 01/16] log_dump: Dump current system states log_dump is command line tool which is used to dump current system states. The system states include from dump_systemstate's output to application/module/system logs. Further logs can be dumped by the scripts that would be installed into dump_scripts directory. Change-Id: Icb60ba85afc8b3d4fbec99e822ad20b8c8a2d36d Signed-off-by: Sunmin Lee --- CMakeLists.txt | 2 +- dump_scripts/app_log.sh | 13 +++ dump_scripts/module_log.sh | 19 ++++ dump_scripts/system_log.sh | 12 +++ packaging/crash-worker.spec | 13 ++- src/dump_systemstate/CMakeLists.txt | 6 +- src/log_dump/CMakeLists.txt | 28 +++++ src/log_dump/log_dump.c | 198 ++++++++++++++++++++++++++++++++++++ src/sys-assert/CMakeLists.txt | 6 +- 9 files changed, 289 insertions(+), 8 deletions(-) create mode 100755 dump_scripts/app_log.sh create mode 100755 dump_scripts/module_log.sh create mode 100755 dump_scripts/system_log.sh create mode 100644 src/log_dump/CMakeLists.txt create mode 100644 src/log_dump/log_dump.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f65b81..4eaaec1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,4 +14,4 @@ ADD_SUBDIRECTORY(src/crash-pipe) ADD_SUBDIRECTORY(src/crash-stack) ADD_SUBDIRECTORY(src/dump_systemstate) - +ADD_SUBDIRECTORY(src/log_dump) diff --git a/dump_scripts/app_log.sh b/dump_scripts/app_log.sh new file mode 100755 index 0000000..bd2dd35 --- /dev/null +++ b/dump_scripts/app_log.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +# Dump application log +# +PATH=/bin:/usr/bin:/sbin:/usr/sbin + +DUMP_DEST=$1/app_log + +. /etc/tizen-platform.conf + +mkdir -p ${DUMP_DEST} + +/bin/mv ${TZ_SYS_CRASH}/* ${DUMP_DEST} diff --git a/dump_scripts/module_log.sh b/dump_scripts/module_log.sh new file mode 100755 index 0000000..8e1a187 --- /dev/null +++ b/dump_scripts/module_log.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Dump module log +# +PATH=/bin:/usr/bin:/sbin:/usr/sbin + +DUMP_DEST=$1/module_log +DUMP_SCRIPT_DIR=/opt/etc/dump.d/module.d + +mkdir -p ${DUMP_DEST} + +if [ -d ${DUMP_SCRIPT_DIR} ] +then + SCRIPTS=`/bin/ls ${DUMP_SCRIPT_DIR}` + + for SCRIPT in ${SCRIPTS}; do + /bin/sh ${DUMP_SCRIPT_DIR}/${SCRIPT} ${DUMP_DEST} + done +fi diff --git a/dump_scripts/system_log.sh b/dump_scripts/system_log.sh new file mode 100755 index 0000000..6d57f64 --- /dev/null +++ b/dump_scripts/system_log.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# Dump system log +# +PATH=/bin:/usr/bin:/sbin:/usr/sbin + +DUMP_DEST=$1/system_log + +mkdir -p ${DUMP_DEST} + +/bin/cp -fr /opt/var/log/* ${DUMP_DEST} +/bin/cp -fr /run/systemd/journal ${DUMP_DEST} diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 3b98404..4e12337 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -10,6 +10,7 @@ Source0: %{name}-%{version}.tar.gz Source1001: crash-worker.manifest BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(capi-system-info) BuildRequires: cmake %if "%{?sys_assert}" == "on" BuildRequires: pkgconfig(libunwind) @@ -37,6 +38,10 @@ crash-manager %define crash_path %{TZ_SYS_CRASH} %define crash_temp %{crash_root_path}/temp +#Path for log_dump module +%define crash_all_log %{TZ_SYS_ALLLOGS} +%define crash_dump_gen %{TZ_SYS_DUMPGEN} + %define upgrade_script_path %{TZ_SYS_RO_SHARE}/upgrade/scripts %build @@ -82,7 +87,10 @@ mkdir -p %{buildroot}%{crash_root_path} mkdir -p %{buildroot}%{crash_path} mkdir -p %{buildroot}%{crash_temp} - +# log_dump dir +mkdir -p %{buildroot}%{crash_all_log} +mkdir -p %{buildroot}%{crash_dump_gen} +cp dump_scripts/* %{buildroot}%{crash_dump_gen} %if "%{?sys_assert}" == "on" @@ -119,8 +127,11 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %dir %{crash_root_path} %dir %{crash_path} %dir %{crash_temp} +%dir %{crash_all_log} +%{crash_dump_gen}/* %attr(0755,system,system) %{_bindir}/dump_systemstate %attr(0755,system,system) %{_bindir}/crash-manager.sh +%attr(0755,system,system) %{_bindir}/log_dump %{_prefix}/lib/sysctl.d/99-crash-manager.conf %if "%{?sys_assert}" == "on" diff --git a/src/dump_systemstate/CMakeLists.txt b/src/dump_systemstate/CMakeLists.txt index bd00d95..85585ce 100755 --- a/src/dump_systemstate/CMakeLists.txt +++ b/src/dump_systemstate/CMakeLists.txt @@ -8,9 +8,9 @@ SET(SRCS ) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED dlog libunwind) +pkg_check_modules(dump_systemstate_pkgs REQUIRED dlog libunwind) -FOREACH(flag ${pkgs_CFLAGS}) +FOREACH(flag ${dump_systemstate_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) @@ -20,7 +20,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") MESSAGE("FLAGS: ${CMAKE_C_FLAGS}") ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${dump_systemstate_pkgs_LDFLAGS}) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt new file mode 100644 index 0000000..8920559 --- /dev/null +++ b/src/log_dump/CMakeLists.txt @@ -0,0 +1,28 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(log_dump C) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) +SET(LOG_DUMP_SRCS + log_dump.c + ${CMAKE_SOURCE_DIR}/src/shared/util.c + ) + +INCLUDE(FindPkgConfig) +pkg_check_modules(log_dump_pkgs REQUIRED + dlog + capi-system-info + libtzplatform-config + ) + +FOREACH(flag ${log_dump_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_EXECUTABLE(${PROJECT_NAME} ${LOG_DUMP_SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${log_dump_pkgs_LDFLAGS}) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c new file mode 100644 index 0000000..38180f5 --- /dev/null +++ b/src/log_dump/log_dump.c @@ -0,0 +1,198 @@ +/* log_dump: dump current system states + * + * Copyright (c) 2016 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shared/util.h" + +#undef LOG_TAG +#define LOG_TAG "LOG_DUMP" +#define LOG_DUMP_ROOT tzplatform_getenv(TZ_SYS_ALLLOGS) +#define LOG_DUMP_DIR tzplatform_mkpath(TZ_SYS_ALLLOGS, "dump") +#define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN) +#define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string" + +enum { + OPT_NORMAL, + OPT_SHORT, +}; + +static const struct option opts[] = { + { "normal", no_argument, 0, OPT_NORMAL }, + { "short", no_argument, 0, OPT_SHORT }, + { 0, 0, 0, 0 } +}; + +static inline void usage(void) +{ + printf("Usage: log_dump [OPTION]\n"); + printf("Dump options:\n"); + printf(" %-10s %s (%s)\n", "--normal", + "dump all logs", DUMP_SCRIPTS_DIR); + printf(" %-10s %s\n", "--short", + "dump systemstate only"); +} + +static int dump_scripts(const char *path) +{ + struct dirent **dir_list = NULL; + char command[PATH_MAX]; + int script_num, i; + + script_num = scandir(path, &dir_list, NULL, NULL); + if (script_num < 0) { + LOGE("Failed to scandir"); + return -1; + } + + for (i = 0; i < script_num; i++) { + if (dir_list[i]->d_type != DT_REG) + continue; + + snprintf(command, sizeof(command), "%s/%s %s", + path, dir_list[i]->d_name, + LOG_DUMP_DIR); + LOGD("%s", command); + system_command(command); + } + + for (i = 0; i < script_num; i++) + free(dir_list[i]); + free(dir_list); + + return 0; +} + +int main(int argc, char *argv[]) +{ + int c, ret; + int opt_normal, opt_short; + char *version_str = NULL; + char timestr[80]; + char command[PATH_MAX]; + char dump_filename[NAME_MAX]; + time_t cur_time; + struct tm loc_tm; + + if (argc < 2) { + usage(); + exit(EXIT_SUCCESS); + } + + opt_normal = opt_short = 0; + while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) { + switch (c) { + case OPT_NORMAL: + opt_normal = 1; + break; + case OPT_SHORT: + opt_short = 1; + break; + default: + usage(); + exit(EXIT_SUCCESS); + break; + } + } + + if (opt_normal & opt_short) { + usage(); + exit(EXIT_SUCCESS); + } + + /* Make debug directory */ + ret = snprintf(command, sizeof(command), + "/usr/bin/mkdir -p %s", LOG_DUMP_DIR); + if (ret < 0) { + LOGE("Failed to mkdir"); + exit(EXIT_FAILURE); + } + system_command(command); + + /* Get timestamp */ + cur_time = time(NULL); + localtime_r(&cur_time, &loc_tm); + strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", &loc_tm); + + /* Get version */ + ret = system_info_get_platform_string(SYSTEM_INFO_KEY_BUILD_STRING, + &version_str); + if (ret != SYSTEM_INFO_ERROR_NONE) { + LOGE("Failed to system_info_get_platform_string"); + version_str = NULL; + } + + /* Dump system states */ + ret = snprintf(command, sizeof(command), + "/usr/bin/dump_systemstate -k -d -f " + "%s/dump_systemstate_%s.log", LOG_DUMP_DIR, timestr); + if (ret < 0) { + LOGE("Failed to snprintf for command"); + exit(EXIT_FAILURE); + } + system_command(command); + + /* Dump all logs */ + if (opt_normal) + dump_scripts(DUMP_SCRIPTS_DIR); + + if (version_str) { + ret = snprintf(dump_filename, sizeof(dump_filename), "%s_%s", + "log_dump", version_str); + if (ret < 0) { + LOGE("Failed to snprintf for dump path"); + exit(EXIT_FAILURE); + } + } else { + ret = snprintf(dump_filename, sizeof(dump_filename), "%s", + "log_dump"); + if (ret < 0) { + LOGE("Failed to snprintf for dump path"); + exit(EXIT_FAILURE); + } + } + + /* Compression */ + ret = snprintf(command, sizeof(command), + "/bin/tar -zcf %s/%s%s.tar.gz -C %s dump", + LOG_DUMP_ROOT, dump_filename, timestr, LOG_DUMP_ROOT); + if (ret < 0) { + LOGE("Failed to snprintf for command"); + exit(EXIT_FAILURE); + } + system_command(command); + + sync(); + + if (remove_dir(LOG_DUMP_DIR, 0) < 0) { + ret = -1; + LOGE("Failed to delete dump directory"); + } + + if (version_str) + free(version_str); + + return ret; +} diff --git a/src/sys-assert/CMakeLists.txt b/src/sys-assert/CMakeLists.txt index 9656d52..99d3383 100644 --- a/src/sys-assert/CMakeLists.txt +++ b/src/sys-assert/CMakeLists.txt @@ -38,9 +38,9 @@ ENDIF("${ARCH_BIT}" STREQUAL "64") INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE(FindPkgConfig) -pkg_check_modules(ppkgs REQUIRED libtzplatform-config libunwind) +pkg_check_modules(sys-assert_pkgs REQUIRED libtzplatform-config libunwind) -FOREACH(flag ${ppkgs_CFLAGS}) +FOREACH(flag ${sys-assert_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) @@ -56,7 +56,7 @@ IF("${ARCH}" STREQUAL "arm") ENDIF("${ARCH}" STREQUAL "arm") ADD_LIBRARY(${LIBNAME} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES(${LIBNAME} ${ppkgs_LDFLAGS} -ldl) +TARGET_LINK_LIBRARIES(${LIBNAME} ${sys-assert_pkgs_LDFLAGS} -ldl) INSTALL(TARGETS ${LIBNAME} LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -- 2.7.4 From f84c7115b4e7a3fd1d2899d0e1892e5c492dd469 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Mon, 7 Nov 2016 18:02:57 +0900 Subject: [PATCH 02/16] log_dump: triggered by dbus method call Add dbus activation feature to log_dump. It handles two method: normal_dump, short_dump. Each method corresponds to the options of log_dump. Change-Id: I3384954f70c55fb7990fe9c5e14405ba63673a63 Signed-off-by: Sunmin Lee --- packaging/crash-worker.spec | 6 +- src/log_dump/CMakeLists.txt | 5 + src/log_dump/dbus-handler.c | 186 ++++++++++++++++++++++++++++ src/log_dump/dbus-handler.h | 24 ++++ src/log_dump/log_dump.c | 129 +++++++++++-------- src/log_dump/log_dump.h | 34 +++++ src/log_dump/org.tizen.system.crash.service | 5 + 7 files changed, 337 insertions(+), 52 deletions(-) create mode 100644 src/log_dump/dbus-handler.c create mode 100644 src/log_dump/dbus-handler.h create mode 100644 src/log_dump/log_dump.h create mode 100644 src/log_dump/org.tizen.system.crash.service diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 4e12337..3fa1212 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -2,7 +2,7 @@ Name: crash-worker Summary: Crash-manager -Version: 0.2.0 +Version: 0.3.0 Release: 1 Group: Framework/system License: Apache-2.0 and PD @@ -11,6 +11,7 @@ Source1001: crash-worker.manifest BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(glib-2.0) BuildRequires: cmake %if "%{?sys_assert}" == "on" BuildRequires: pkgconfig(libunwind) @@ -118,8 +119,6 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %endif - - %files %license LICENSE %manifest crash-worker.manifest @@ -133,6 +132,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %attr(0755,system,system) %{_bindir}/crash-manager.sh %attr(0755,system,system) %{_bindir}/log_dump %{_prefix}/lib/sysctl.d/99-crash-manager.conf +%{_datadir}/dbus-1/system-services/org.tizen.system.crash.service %if "%{?sys_assert}" == "on" %{_libdir}/libsys-assert.so diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt index 8920559..12bab7e 100644 --- a/src/log_dump/CMakeLists.txt +++ b/src/log_dump/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(log_dump C) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) SET(LOG_DUMP_SRCS log_dump.c + dbus-handler.c ${CMAKE_SOURCE_DIR}/src/shared/util.c ) @@ -12,6 +13,8 @@ pkg_check_modules(log_dump_pkgs REQUIRED dlog capi-system-info libtzplatform-config + glib-2.0 + gio-2.0 ) FOREACH(flag ${log_dump_pkgs_CFLAGS}) @@ -23,6 +26,8 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") ADD_EXECUTABLE(${PROJECT_NAME} ${LOG_DUMP_SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${log_dump_pkgs_LDFLAGS}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.system.crash.service + DESTINATION /usr/share/dbus-1/system-services) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/src/log_dump/dbus-handler.c b/src/log_dump/dbus-handler.c new file mode 100644 index 0000000..adfe7ac --- /dev/null +++ b/src/log_dump/dbus-handler.c @@ -0,0 +1,186 @@ +/* + * log_dump + * + * Copyright (c) 2016 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 +#include +#include +#include "log_dump.h" +#include "dbus-handler.h" + +#define CRASH_BUS_NAME "org.tizen.system.crash" +#define CRASH_BUS_PATH "/Org/Tizen/System/Crash" + +#define TIMEOUT_INTERVAL 30 + +static GMainLoop *loop; +static GMutex timeout_mutex; +static guint timeout_id; +static GDBusNodeInfo *introspection_data; +static const gchar introspection_xml[] = +"" +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static int timeout_cb(gpointer data) +{ + LOGI("Time out!"); + g_main_loop_quit((GMainLoop *)data); + + return 0; +} + +static void add_timeout(void) +{ + g_mutex_lock(&timeout_mutex); + + if (timeout_id) + g_source_remove(timeout_id); + timeout_id = g_timeout_add_seconds(TIMEOUT_INTERVAL, timeout_cb, loop); + + g_mutex_unlock(&timeout_mutex); + LOGI("Add loop timeout (%d)", TIMEOUT_INTERVAL); +} + +static void remove_timeout(void) +{ + g_mutex_lock(&timeout_mutex); + + if (timeout_id) { + g_source_remove(timeout_id); + timeout_id = 0; + } + + g_mutex_unlock(&timeout_mutex); + LOGI("Remove loop timeout"); +} + +static void method_call_handler(GDBusConnection *conn, + const gchar *sender, + const gchar *object_path, + const gchar *iface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + int ret = -1; + int option = -1; + + remove_timeout(); + + if (g_strcmp0(method_name, "normal_dump") == 0) + option = OPT_NORMAL; + else if (g_strcmp0(method_name, "short_dump") == 0) + option = OPT_SHORT; + + if (option >= 0) + ret = log_dump(option); + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", ret)); + + add_timeout(); +} + +static const GDBusInterfaceVTable interface_vtable = { + method_call_handler, + NULL, + NULL +}; + +static void on_bus_acquired(GDBusConnection *conn, + const gchar *name, + gpointer user_data) +{ + guint registration_id; + + registration_id = g_dbus_connection_register_object(conn, + CRASH_BUS_PATH, introspection_data->interfaces[0], + &interface_vtable, NULL, NULL, NULL); + if (registration_id == 0) + LOGE("Failed to g_dbus_connection_register_object"); +} + +static void on_name_acquired(GDBusConnection *conn, + const gchar *name, + gpointer user_data) +{ + LOGD("Acquired the name %s on the system bus", name); +} + +static void on_name_lost(GDBusConnection *conn, + const gchar *name, + gpointer user_data) +{ + LOGD("Lost the name %s on the system bus", name); +} + +static void dbus_init(void) +{ + GDBusConnection *conn = NULL; + GError *error = NULL; + + introspection_data = + g_dbus_node_info_new_for_xml(introspection_xml, NULL); + if (introspection_data == NULL) { + LOGE("Failed to init g_dbus_info_new_for_xml"); + return; + } + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (!conn) { + LOGE("Failed to get dbus"); + return; + } + + if (error) { + LOGE("Failed to get dbus"); + g_error_free(error); + return; + } + + g_bus_own_name(G_BUS_TYPE_SYSTEM, CRASH_BUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, + on_name_acquired, on_name_lost, NULL, NULL); +} + +int log_dump_dbus(void) +{ + loop = g_main_loop_new(NULL, false); + + dbus_init(); + + g_mutex_init(&timeout_mutex); + add_timeout(); + + LOGI("log_dump_dbus activated"); + g_main_loop_run(loop); + + if (introspection_data) + g_dbus_node_info_unref(introspection_data); + g_mutex_clear(&timeout_mutex); + g_main_loop_unref(loop); + + return 0; +} diff --git a/src/log_dump/dbus-handler.h b/src/log_dump/dbus-handler.h new file mode 100644 index 0000000..0d3d5d9 --- /dev/null +++ b/src/log_dump/dbus-handler.h @@ -0,0 +1,24 @@ +/* + * log_dump + * + * Copyright (c) 2016 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 __LOGDUMP_DBUS_H__ +#define __LOGDUMP_DBUS_H__ + +int log_dump_dbus(void); + +#endif diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c index 38180f5..cdfa7f0 100644 --- a/src/log_dump/log_dump.c +++ b/src/log_dump/log_dump.c @@ -1,4 +1,5 @@ -/* log_dump: dump current system states +/* + * log_dump: dump current system states * * Copyright (c) 2016 Samsung Electronics Co., Ltd. * @@ -22,10 +23,11 @@ #include #include #include -#include #include #include #include "shared/util.h" +#include "log_dump.h" +#include "dbus-handler.h" #undef LOG_TAG #define LOG_TAG "LOG_DUMP" @@ -34,14 +36,10 @@ #define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN) #define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string" -enum { - OPT_NORMAL, - OPT_SHORT, -}; - static const struct option opts[] = { { "normal", no_argument, 0, OPT_NORMAL }, { "short", no_argument, 0, OPT_SHORT }, + { "dbus", no_argument, 0, OPT_DBUS }, { 0, 0, 0, 0 } }; @@ -53,6 +51,8 @@ static inline void usage(void) "dump all logs", DUMP_SCRIPTS_DIR); printf(" %-10s %s\n", "--short", "dump systemstate only"); + printf(" %-10s %s\n", "--dbus", + "activate dbus interface"); } static int dump_scripts(const char *path) @@ -85,10 +85,9 @@ static int dump_scripts(const char *path) return 0; } -int main(int argc, char *argv[]) +int log_dump(int option) { - int c, ret; - int opt_normal, opt_short; + int ret; char *version_str = NULL; char timestr[80]; char command[PATH_MAX]; @@ -96,40 +95,16 @@ int main(int argc, char *argv[]) time_t cur_time; struct tm loc_tm; - if (argc < 2) { - usage(); - exit(EXIT_SUCCESS); - } - - opt_normal = opt_short = 0; - while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) { - switch (c) { - case OPT_NORMAL: - opt_normal = 1; - break; - case OPT_SHORT: - opt_short = 1; - break; - default: - usage(); - exit(EXIT_SUCCESS); - break; - } - } - - if (opt_normal & opt_short) { - usage(); - exit(EXIT_SUCCESS); - } - /* Make debug directory */ - ret = snprintf(command, sizeof(command), - "/usr/bin/mkdir -p %s", LOG_DUMP_DIR); - if (ret < 0) { - LOGE("Failed to mkdir"); - exit(EXIT_FAILURE); + if (access(LOG_DUMP_DIR, F_OK) != 0) { + ret = snprintf(command, sizeof(command), + "/usr/bin/mkdir -p %s", LOG_DUMP_DIR); + if (ret < 0) { + LOGE("Failed to mkdir"); + return -1; + } + system_command(command); } - system_command(command); /* Get timestamp */ cur_time = time(NULL); @@ -150,12 +125,12 @@ int main(int argc, char *argv[]) "%s/dump_systemstate_%s.log", LOG_DUMP_DIR, timestr); if (ret < 0) { LOGE("Failed to snprintf for command"); - exit(EXIT_FAILURE); + goto exit; } system_command(command); /* Dump all logs */ - if (opt_normal) + if (option == OPT_NORMAL) dump_scripts(DUMP_SCRIPTS_DIR); if (version_str) { @@ -163,14 +138,14 @@ int main(int argc, char *argv[]) "log_dump", version_str); if (ret < 0) { LOGE("Failed to snprintf for dump path"); - exit(EXIT_FAILURE); + goto exit; } } else { ret = snprintf(dump_filename, sizeof(dump_filename), "%s", "log_dump"); if (ret < 0) { LOGE("Failed to snprintf for dump path"); - exit(EXIT_FAILURE); + return -1; } } @@ -180,19 +155,75 @@ int main(int argc, char *argv[]) LOG_DUMP_ROOT, dump_filename, timestr, LOG_DUMP_ROOT); if (ret < 0) { LOGE("Failed to snprintf for command"); - exit(EXIT_FAILURE); + goto exit; } system_command(command); sync(); - if (remove_dir(LOG_DUMP_DIR, 0) < 0) { - ret = -1; + ret = remove_dir(LOG_DUMP_DIR, 0); + if (ret < 0) { LOGE("Failed to delete dump directory"); + goto exit; } + /* Further operations for log_dump here */ + +exit: if (version_str) free(version_str); return ret; } + +int main(int argc, char *argv[]) +{ + int c, ret; + int option; + + if (argc < 2) { + usage(); + exit(EXIT_SUCCESS); + } + + option = -1; + while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) { + switch (c) { + case OPT_NORMAL: + if (option >= 0) { + usage(); + exit(EXIT_SUCCESS); + } + option = OPT_NORMAL; + break; + case OPT_SHORT: + if (option >= 0) { + usage(); + exit(EXIT_SUCCESS); + } + option = OPT_SHORT; + break; + case OPT_DBUS: + if (option >= 0) { + usage(); + exit(EXIT_SUCCESS); + } + option = OPT_DBUS; + break; + default: + usage(); + exit(EXIT_SUCCESS); + break; + } + } + + if (option == OPT_DBUS) + ret = log_dump_dbus(); + else + ret = log_dump(option); + + if (ret < 0) + exit(EXIT_FAILURE); + + return 0; +} diff --git a/src/log_dump/log_dump.h b/src/log_dump/log_dump.h new file mode 100644 index 0000000..9936a08 --- /dev/null +++ b/src/log_dump/log_dump.h @@ -0,0 +1,34 @@ +/* + * log_dump + * + * Copyright (c) 2016 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 __LOGDUMP_H__ +#define __LOGDUMP_H__ + +#include +#undef LOG_TAG +#define LOG_TAG "LOG_DUMP" + +enum { + OPT_NORMAL, + OPT_SHORT, + OPT_DBUS, +}; + +int log_dump(int option); + +#endif diff --git a/src/log_dump/org.tizen.system.crash.service b/src/log_dump/org.tizen.system.crash.service new file mode 100644 index 0000000..1e9a605 --- /dev/null +++ b/src/log_dump/org.tizen.system.crash.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.system.crash +Exec=/usr/bin/log_dump --dbus +User=root +Group=root -- 2.7.4 From 4f323ad86fcd30c30e36438c4f7933f4a8740b0f Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Tue, 8 Nov 2016 14:32:29 +0900 Subject: [PATCH 03/16] log_dump: change log_dump output directories TZ_SYS_ALLLOGS: log_dump's destination directory. TZ_SYS_CRASH_ROOT: the compressed log file would be placed in TZ_SYS_CRASH_ROOT. Change-Id: I2abaa253de39c0eaceffd7b61b09ca649ef88026 Signed-off-by: Sunmin Lee --- src/log_dump/log_dump.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c index cdfa7f0..9763685 100644 --- a/src/log_dump/log_dump.c +++ b/src/log_dump/log_dump.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "shared/util.h" @@ -31,8 +32,8 @@ #undef LOG_TAG #define LOG_TAG "LOG_DUMP" -#define LOG_DUMP_ROOT tzplatform_getenv(TZ_SYS_ALLLOGS) -#define LOG_DUMP_DIR tzplatform_mkpath(TZ_SYS_ALLLOGS, "dump") +#define LOG_DUMP_ROOT tzplatform_getenv(TZ_SYS_CRASH_ROOT) +#define LOG_DUMP_DIR tzplatform_getenv(TZ_SYS_ALLLOGS) #define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN) #define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string" @@ -55,13 +56,13 @@ static inline void usage(void) "activate dbus interface"); } -static int dump_scripts(const char *path) +static int dump_scripts(void) { struct dirent **dir_list = NULL; char command[PATH_MAX]; int script_num, i; - script_num = scandir(path, &dir_list, NULL, NULL); + script_num = scandir(DUMP_SCRIPTS_DIR, &dir_list, NULL, NULL); if (script_num < 0) { LOGE("Failed to scandir"); return -1; @@ -72,7 +73,7 @@ static int dump_scripts(const char *path) continue; snprintf(command, sizeof(command), "%s/%s %s", - path, dir_list[i]->d_name, + DUMP_SCRIPTS_DIR, dir_list[i]->d_name, LOG_DUMP_DIR); LOGD("%s", command); system_command(command); @@ -89,6 +90,7 @@ int log_dump(int option) { int ret; char *version_str = NULL; + char *dump_dirname = NULL; char timestr[80]; char command[PATH_MAX]; char dump_filename[NAME_MAX]; @@ -131,7 +133,7 @@ int log_dump(int option) /* Dump all logs */ if (option == OPT_NORMAL) - dump_scripts(DUMP_SCRIPTS_DIR); + dump_scripts(); if (version_str) { ret = snprintf(dump_filename, sizeof(dump_filename), "%s_%s", @@ -150,9 +152,16 @@ int log_dump(int option) } /* Compression */ + dump_dirname = strdup(LOG_DUMP_DIR); + if (!dump_dirname) { + LOGE("Failed to strdup for dump_dirname"); + goto exit; + } + ret = snprintf(command, sizeof(command), - "/bin/tar -zcf %s/%s%s.tar.gz -C %s dump", - LOG_DUMP_ROOT, dump_filename, timestr, LOG_DUMP_ROOT); + "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s", + LOG_DUMP_ROOT, dump_filename, timestr, LOG_DUMP_ROOT, + basename(dump_dirname)); if (ret < 0) { LOGE("Failed to snprintf for command"); goto exit; @@ -172,6 +181,8 @@ int log_dump(int option) exit: if (version_str) free(version_str); + if (dump_dirname) + free(dump_dirname); return ret; } -- 2.7.4 From dd1a331592a45a006f7460177bb95a28c15e9971 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Tue, 8 Nov 2016 19:16:59 +0900 Subject: [PATCH 04/16] log_dump: seperate crash dump from log_dump The crash dump means output of crash-manager triggered by crashed apps. These logs will be compressed together when OPT_NORMAL option rather than be moved into log_dump's output by app_log.sh. Change-Id: Ib2588176de217d16a37b7a916fd765016b4b8862 Signed-off-by: Sunmin Lee --- dump_scripts/app_log.sh | 13 ------------- src/log_dump/log_dump.c | 44 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 20 deletions(-) delete mode 100755 dump_scripts/app_log.sh diff --git a/dump_scripts/app_log.sh b/dump_scripts/app_log.sh deleted file mode 100755 index bd2dd35..0000000 --- a/dump_scripts/app_log.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# -# Dump application log -# -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -DUMP_DEST=$1/app_log - -. /etc/tizen-platform.conf - -mkdir -p ${DUMP_DEST} - -/bin/mv ${TZ_SYS_CRASH}/* ${DUMP_DEST} diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c index 9763685..8459e73 100644 --- a/src/log_dump/log_dump.c +++ b/src/log_dump/log_dump.c @@ -34,6 +34,7 @@ #define LOG_TAG "LOG_DUMP" #define LOG_DUMP_ROOT tzplatform_getenv(TZ_SYS_CRASH_ROOT) #define LOG_DUMP_DIR tzplatform_getenv(TZ_SYS_ALLLOGS) +#define CRASH_DUMP_DIR tzplatform_getenv(TZ_SYS_CRASH) #define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN) #define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string" @@ -91,6 +92,7 @@ int log_dump(int option) int ret; char *version_str = NULL; char *dump_dirname = NULL; + char *crash_dirname = NULL; char timestr[80]; char command[PATH_MAX]; char dump_filename[NAME_MAX]; @@ -158,23 +160,49 @@ int log_dump(int option) goto exit; } - ret = snprintf(command, sizeof(command), - "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s", - LOG_DUMP_ROOT, dump_filename, timestr, LOG_DUMP_ROOT, - basename(dump_dirname)); - if (ret < 0) { - LOGE("Failed to snprintf for command"); - goto exit; + if (option == OPT_NORMAL) { + crash_dirname = strdup(CRASH_DUMP_DIR); + if (!crash_dirname) { + LOGE("Failed to strdup for dump_dirname"); + goto exit; + } + + ret = snprintf(command, sizeof(command), + "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s %s", + LOG_DUMP_ROOT, dump_filename, timestr, + LOG_DUMP_ROOT, basename(dump_dirname), + basename(crash_dirname)); + if (ret < 0) { + LOGE("Failed to snprintf for command"); + goto exit; + } + } else { + ret = snprintf(command, sizeof(command), + "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s", + LOG_DUMP_ROOT, dump_filename, timestr, + LOG_DUMP_ROOT, basename(dump_dirname)); + if (ret < 0) { + LOGE("Failed to snprintf for command"); + goto exit; + } } system_command(command); sync(); + /* Remove gatherd dump */ ret = remove_dir(LOG_DUMP_DIR, 0); if (ret < 0) { LOGE("Failed to delete dump directory"); goto exit; } + if (option == OPT_NORMAL) { + ret = remove_dir(CRASH_DUMP_DIR, 0); + if (ret < 0) { + LOGE("Failed to delete crash dump directory"); + goto exit; + } + } /* Further operations for log_dump here */ @@ -183,6 +211,8 @@ exit: free(version_str); if (dump_dirname) free(dump_dirname); + if (crash_dirname) + free(crash_dirname); return ret; } -- 2.7.4 From 3fa45c79662270921cb7c7c5a58468d04d264aab Mon Sep 17 00:00:00 2001 From: Kunhoon Baik Date: Fri, 11 Nov 2016 21:24:43 +0900 Subject: [PATCH 05/16] Guarantee the completion of crash worker To handle process information in several process, The kernel needs to wait for usermode-helper process to be finished. For supporting the usermode-helper process completion, use core_pipe_limit. Change-Id: I1035c26cc3780fb3a8ddeded351b4e4a00ad546d --- src/crash-manager/99-crash-manager.conf.in | 1 + src/crash-manager/crash-manager.sh.in | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/crash-manager/99-crash-manager.conf.in b/src/crash-manager/99-crash-manager.conf.in index 32ba9bc..8277deb 100644 --- a/src/crash-manager/99-crash-manager.conf.in +++ b/src/crash-manager/99-crash-manager.conf.in @@ -1,2 +1,3 @@ # Tizen crash-manager kernel.core_pattern=|/usr/bin/crash-manager.sh %p %u %g %s %t %e +kernel.core_pipe_limit=10 diff --git a/src/crash-manager/crash-manager.sh.in b/src/crash-manager/crash-manager.sh.in index 965a149..7e1d607 100644 --- a/src/crash-manager/crash-manager.sh.in +++ b/src/crash-manager/crash-manager.sh.in @@ -50,10 +50,8 @@ then then mv "$sysassert_cs_path" "$pfx/" fi - @CRASH_STACK_PATH@ --pid "$pid" > "$tmp_callstack_path" @CRASH_PIPE_PATH@ --save-core "$core_path" --report "$@" > "$info_path" - cat "$tmp_callstack_path" >> "$info_path" - rm "$tmp_callstack_path" + @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" else @CRASH_PIPE_PATH@ --report "$@" > "$info_path" @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" -- 2.7.4 From b153665a12cda6a29f9ba9d12db7f2682ade9af5 Mon Sep 17 00:00:00 2001 From: taeyoung Date: Fri, 18 Nov 2016 22:52:29 +0900 Subject: [PATCH 06/16] engineer mode: make .debugmode on engineer image - .debugmode file makes platform to launch crash popup when crash is occurred Change-Id: Id7bd88b534f1dd1aa86eab12cfcef6e8b48332ab Signed-off-by: taeyoung --- packaging/crash-worker.spec | 17 +++++++++++++++++ src/crash-manager/debugmode | 0 2 files changed, 17 insertions(+) create mode 100644 src/crash-manager/debugmode diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 3fa1212..6c5101f 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -45,6 +45,9 @@ crash-manager %define upgrade_script_path %{TZ_SYS_RO_SHARE}/upgrade/scripts +#Engineer mode +%define eng_mode_path %{TZ_SYS_ETC} + %build cp %{SOURCE1001} . @@ -62,6 +65,12 @@ export CFLAGS+=" -Werror" %define ARCH_BIT 64 %endif +%if 0%{?tizen_build_devel_mode} + %define eng_mode on +%else + %define eng_mode off +%endif + %cmake . \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DTMP_FILES_DIR=%{_sysconfdir}/tmpfiles.d \ @@ -93,6 +102,10 @@ mkdir -p %{buildroot}%{crash_all_log} mkdir -p %{buildroot}%{crash_dump_gen} cp dump_scripts/* %{buildroot}%{crash_dump_gen} +%if "%{eng_mode}" == "on" +install -m 644 src/crash-manager/debugmode %{buildroot}%{eng_mode_path}/.debugmode +%endif + %if "%{?sys_assert}" == "on" %post @@ -142,5 +155,9 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %{_libexecdir}/crash-pipe %{_libexecdir}/crash-stack +%if "%{eng_mode}" == "on" +%{eng_mode_path}/.debugmode +%endif + #upgrade script %attr(-,root,root) %{upgrade_script_path}/crash-manager-upgrade.sh diff --git a/src/crash-manager/debugmode b/src/crash-manager/debugmode new file mode 100644 index 0000000..e69de29 -- 2.7.4 From 1dde86192369f93644ec226b8aef348f5a00f1fd Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Tue, 22 Nov 2016 13:56:38 +0900 Subject: [PATCH 07/16] Change executable to shared object Because of security issue, executables made by crash-worker should be shared object. Change-Id: I898b8c2f7b6e70366e69d56339fc355ef4c33944 Signed-off-by: Sunmin Lee --- src/dump_systemstate/CMakeLists.txt | 4 ++-- src/log_dump/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dump_systemstate/CMakeLists.txt b/src/dump_systemstate/CMakeLists.txt index 85585ce..d15805b 100755 --- a/src/dump_systemstate/CMakeLists.txt +++ b/src/dump_systemstate/CMakeLists.txt @@ -16,11 +16,11 @@ ENDFOREACH(flag) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") MESSAGE("FLAGS: ${CMAKE_C_FLAGS}") ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${dump_systemstate_pkgs_LDFLAGS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${dump_systemstate_pkgs_LDFLAGS} -pie) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt index 12bab7e..8124a79 100644 --- a/src/log_dump/CMakeLists.txt +++ b/src/log_dump/CMakeLists.txt @@ -21,10 +21,10 @@ FOREACH(flag ${log_dump_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") ADD_EXECUTABLE(${PROJECT_NAME} ${LOG_DUMP_SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${log_dump_pkgs_LDFLAGS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${log_dump_pkgs_LDFLAGS} -pie) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.system.crash.service DESTINATION /usr/share/dbus-1/system-services) -- 2.7.4 From f222a14894e45944240e9e3a84c61a551367c3cc Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Mon, 21 Nov 2016 14:03:36 +0900 Subject: [PATCH 08/16] Several modifications for backward compatibility 1) Change log_dump dbus path and interface. 2) Add delete_dump option to log_dump's dbus interface. 3) Move log_dump's result from CRASH_ROOT to LOG_DUMP_RESULT. 4) tizen-debug on/off services are added. Change-Id: I0257537ad69b524714370c1ecfa11cc9d942a560 Signed-off-by: Sunmin Lee --- packaging/crash-worker.spec | 16 +++++++++----- src/log_dump/CMakeLists.txt | 1 + src/log_dump/dbus-handler.c | 28 ++++++++++++++---------- src/log_dump/log_dump.c | 34 +++++++++++++++++++++++------- src/log_dump/{log_dump.h => log_dump.h.in} | 9 ++++++++ src/sys-assert/CMakeLists.txt | 8 +++++++ src/sys-assert/tizen-debug-off.service | 15 +++++++++++++ src/sys-assert/tizen-debug-on.service | 15 +++++++++++++ 8 files changed, 102 insertions(+), 24 deletions(-) rename src/log_dump/{log_dump.h => log_dump.h.in} (67%) create mode 100644 src/sys-assert/tizen-debug-off.service create mode 100644 src/sys-assert/tizen-debug-on.service diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 6c5101f..b94edff 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -101,14 +101,14 @@ mkdir -p %{buildroot}%{crash_temp} mkdir -p %{buildroot}%{crash_all_log} mkdir -p %{buildroot}%{crash_dump_gen} cp dump_scripts/* %{buildroot}%{crash_dump_gen} +chmod 755 %{buildroot}%{crash_dump_gen}/* %if "%{eng_mode}" == "on" install -m 644 src/crash-manager/debugmode %{buildroot}%{eng_mode_path}/.debugmode %endif -%if "%{?sys_assert}" == "on" - %post +%if "%{?sys_assert}" == "on" if [ ! -d /.build ]; then orig="%{_libdir}/libsys-assert.so" pattern=$(echo $orig | sed -e 's|/|\\/|g') @@ -119,17 +119,21 @@ if [ ! -d /.build ]; then chmod 644 %{_sysconfdir}/ld.so.preload fi +/sbin/ldconfig +%endif + /usr/bin/chsmack -a "System::Shared" -t %{crash_path} /usr/bin/chsmack -a "System::Shared" -t %{crash_temp} - -/sbin/ldconfig +/usr/bin/chsmack -a "System::Shared" -t %{crash_dump_gen} +/usr/bin/chsmack -a "System::Shared" -t %{crash_dump_gen}/module.d +/usr/bin/chsmack -d %{crash_dump_gen}/module.d/* %postun +%if "%{?sys_assert}" == "on" orig="%{_libdir}/libsys-assert.so" pattern=$(echo $orig | sed -e 's|/|\\/|g') sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload /sbin/ldconfig - %endif %files @@ -144,6 +148,8 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %attr(0755,system,system) %{_bindir}/dump_systemstate %attr(0755,system,system) %{_bindir}/crash-manager.sh %attr(0755,system,system) %{_bindir}/log_dump +%attr(0644,root,system) %{_unitdir}/tizen-debug-on.service +%attr(0644,root,system) %{_unitdir}/tizen-debug-off.service %{_prefix}/lib/sysctl.d/99-crash-manager.conf %{_datadir}/dbus-1/system-services/org.tizen.system.crash.service diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt index 8124a79..1d6d220 100644 --- a/src/log_dump/CMakeLists.txt +++ b/src/log_dump/CMakeLists.txt @@ -23,6 +23,7 @@ ENDFOREACH(flag) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") +CONFIGURE_FILE(log_dump.h.in log_dump.h @ONLY) ADD_EXECUTABLE(${PROJECT_NAME} ${LOG_DUMP_SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${log_dump_pkgs_LDFLAGS} -pie) diff --git a/src/log_dump/dbus-handler.c b/src/log_dump/dbus-handler.c index adfe7ac..db87328 100644 --- a/src/log_dump/dbus-handler.c +++ b/src/log_dump/dbus-handler.c @@ -23,7 +23,7 @@ #include "dbus-handler.h" #define CRASH_BUS_NAME "org.tizen.system.crash" -#define CRASH_BUS_PATH "/Org/Tizen/System/Crash" +#define CRASH_BUS_PATH "/Org/Tizen/System/Crash/Crash" #define TIMEOUT_INTERVAL 30 @@ -33,11 +33,12 @@ static guint timeout_id; static GDBusNodeInfo *introspection_data; static const gchar introspection_xml[] = "" -" " -" " +" " +" " +" " " " " " -" " +" " " " " " " " @@ -86,17 +87,22 @@ static void method_call_handler(GDBusConnection *conn, gpointer user_data) { int ret = -1; - int option = -1; + const gchar *arg; remove_timeout(); - if (g_strcmp0(method_name, "normal_dump") == 0) - option = OPT_NORMAL; - else if (g_strcmp0(method_name, "short_dump") == 0) - option = OPT_SHORT; + if (g_strcmp0(method_name, "dump_log") == 0) { + g_variant_get(parameters, "(&s)", &arg); + if (g_strcmp0(arg, "normal") == 0) + ret = log_dump(OPT_NORMAL); + else if (g_strcmp0(arg, "short") == 0) + ret = log_dump(OPT_SHORT); + else + LOGE("Wrong option for log_dump"); + } else if (g_strcmp0(method_name, "delete_dump") == 0) { + ret = delete_dump(); + } - if (option >= 0) - ret = log_dump(option); g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret)); diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c index 8459e73..228112f 100644 --- a/src/log_dump/log_dump.c +++ b/src/log_dump/log_dump.c @@ -25,17 +25,12 @@ #include #include #include -#include #include "shared/util.h" #include "log_dump.h" #include "dbus-handler.h" #undef LOG_TAG #define LOG_TAG "LOG_DUMP" -#define LOG_DUMP_ROOT tzplatform_getenv(TZ_SYS_CRASH_ROOT) -#define LOG_DUMP_DIR tzplatform_getenv(TZ_SYS_ALLLOGS) -#define CRASH_DUMP_DIR tzplatform_getenv(TZ_SYS_CRASH) -#define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN) #define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string" static const struct option opts[] = { @@ -65,7 +60,7 @@ static int dump_scripts(void) script_num = scandir(DUMP_SCRIPTS_DIR, &dir_list, NULL, NULL); if (script_num < 0) { - LOGE("Failed to scandir"); + LOGE("Failed to scandir %s",DUMP_SCRIPTS_DIR); return -1; } @@ -110,6 +105,17 @@ int log_dump(int option) system_command(command); } + /* Make result directory */ + if (access(LOG_DUMP_RESULT, F_OK) != 0) { + ret = snprintf(command, sizeof(command), + "/usr/bin/mkdir -p %s", LOG_DUMP_RESULT); + if (ret < 0) { + LOGE("Failed to mkdir"); + return -1; + } + system_command(command); + } + /* Get timestamp */ cur_time = time(NULL); localtime_r(&cur_time, &loc_tm); @@ -169,7 +175,7 @@ int log_dump(int option) ret = snprintf(command, sizeof(command), "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s %s", - LOG_DUMP_ROOT, dump_filename, timestr, + LOG_DUMP_RESULT, dump_filename, timestr, LOG_DUMP_ROOT, basename(dump_dirname), basename(crash_dirname)); if (ret < 0) { @@ -179,7 +185,7 @@ int log_dump(int option) } else { ret = snprintf(command, sizeof(command), "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s", - LOG_DUMP_ROOT, dump_filename, timestr, + LOG_DUMP_RESULT, dump_filename, timestr, LOG_DUMP_ROOT, basename(dump_dirname)); if (ret < 0) { LOGE("Failed to snprintf for command"); @@ -217,6 +223,18 @@ exit: return ret; } +int delete_dump(void) +{ + LOGI("delete_dump!"); + + remove_dir(LOG_DUMP_DIR, 0); + remove_dir(LOG_DUMP_RESULT, 1); + remove_dir(CRASH_DUMP_DIR, 0); + remove_dir(CRASH_TEMP_DIR, 0); + + return 0; +} + int main(int argc, char *argv[]) { int c, ret; diff --git a/src/log_dump/log_dump.h b/src/log_dump/log_dump.h.in similarity index 67% rename from src/log_dump/log_dump.h rename to src/log_dump/log_dump.h.in index 9936a08..0d39555 100644 --- a/src/log_dump/log_dump.h +++ b/src/log_dump/log_dump.h.in @@ -19,10 +19,18 @@ #ifndef __LOGDUMP_H__ #define __LOGDUMP_H__ +#include #include #undef LOG_TAG #define LOG_TAG "LOG_DUMP" +#define LOG_DUMP_ROOT tzplatform_getenv(TZ_SYS_CRASH_ROOT) +#define LOG_DUMP_DIR tzplatform_getenv(TZ_SYS_ALLLOGS) +#define LOG_DUMP_RESULT tzplatform_mkpath(TZ_SYS_CRASH_ROOT, "debug") +#define CRASH_DUMP_DIR "@CRASH_PATH@" +#define CRASH_TEMP_DIR "@CRASH_TEMP@" +#define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN) + enum { OPT_NORMAL, OPT_SHORT, @@ -30,5 +38,6 @@ enum { }; int log_dump(int option); +int delete_dump(void); #endif diff --git a/src/sys-assert/CMakeLists.txt b/src/sys-assert/CMakeLists.txt index 99d3383..e6c7ca0 100644 --- a/src/sys-assert/CMakeLists.txt +++ b/src/sys-assert/CMakeLists.txt @@ -62,3 +62,11 @@ INSTALL(TARGETS ${LIBNAME} LIBRARY DESTINATION ${LIB_INSTALL_DIR}) CONFIGURE_FILE(sys-assert.conf.in sys-assert.conf) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/sys-assert.conf DESTINATION ${TMP_FILES_DIR}) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tizen-debug-on.service DESTINATION /usr/lib/systemd/system + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tizen-debug-off.service DESTINATION /usr/lib/systemd/system + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) \ No newline at end of file diff --git a/src/sys-assert/tizen-debug-off.service b/src/sys-assert/tizen-debug-off.service new file mode 100644 index 0000000..870964e --- /dev/null +++ b/src/sys-assert/tizen-debug-off.service @@ -0,0 +1,15 @@ +[Unit] +Description=tizen debug off +DefaultDependencies=no +After=opt.mount tizen-debug-on.service +Before=sysinit.target + +[Service] +SmackProcessLabel=System +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/rm -f /opt/etc/.debugmode +ExecStart=/sbin/sysctl kernel.core_pattern=/dev/null + +[Install] +WantedBy=sysinit.target diff --git a/src/sys-assert/tizen-debug-on.service b/src/sys-assert/tizen-debug-on.service new file mode 100644 index 0000000..22ae97a --- /dev/null +++ b/src/sys-assert/tizen-debug-on.service @@ -0,0 +1,15 @@ +[Unit] +Description=tizen debug on +DefaultDependencies=no +After=opt.mount +Before=sysinit.target + +[Service] +SmackProcessLabel=System +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/touch -f /opt/etc/.debugmode +ExecStart=/sbin/sysctl -p /usr/lib/sysctl.d/99-crash-manager.conf + +[Install] +WantedBy=sysinit.target -- 2.7.4 From b240c43837ccb57d48e75c18f5c4f9f57a07cd3c Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Tue, 15 Nov 2016 10:27:56 +0900 Subject: [PATCH 09/16] log_dump: broadcast start/finish dbus signal log_dump offers start/finish signal so other processes can recognize log_dump's operation in different way rather than waiting it's reply. Change-Id: Id23f181fd820f996071da30c895896850c4c474a --- src/log_dump/dbus-handler.c | 55 +++++++++++++++++++++++++++++++++++++++++---- src/log_dump/dbus-handler.h | 2 ++ src/log_dump/log_dump.c | 4 ++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/log_dump/dbus-handler.c b/src/log_dump/dbus-handler.c index db87328..16274cb 100644 --- a/src/log_dump/dbus-handler.c +++ b/src/log_dump/dbus-handler.c @@ -22,8 +22,16 @@ #include "log_dump.h" #include "dbus-handler.h" -#define CRASH_BUS_NAME "org.tizen.system.crash" -#define CRASH_BUS_PATH "/Org/Tizen/System/Crash/Crash" +/* Dbus activation */ +#define CRASH_BUS_NAME "org.tizen.system.crash" +#define CRASH_OBJECT_PATH "/Org/Tizen/System/Crash/Crash" + +/* Log dump signal */ +#define LOG_DUMP_BUS_NAME "org.tizen.system.logdump" +#define LOG_DUMP_OBJECT_PATH "/Org/Tizen/System/LogDump" +#define LOG_DUMP_INTERFACE_NAME LOG_DUMP_BUS_NAME +#define LOG_DUMP_START_SIGNAL "Start" +#define LOG_DUMP_FINISH_SIGNAL "Finish" #define TIMEOUT_INTERVAL 30 @@ -122,7 +130,7 @@ static void on_bus_acquired(GDBusConnection *conn, guint registration_id; registration_id = g_dbus_connection_register_object(conn, - CRASH_BUS_PATH, introspection_data->interfaces[0], + CRASH_OBJECT_PATH, introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL); if (registration_id == 0) LOGE("Failed to g_dbus_connection_register_object"); @@ -161,7 +169,7 @@ static void dbus_init(void) } if (error) { - LOGE("Failed to get dbus"); + LOGE("Failed to get dbus: %s", error->message); g_error_free(error); return; } @@ -190,3 +198,42 @@ int log_dump_dbus(void) return 0; } + +static int broadcast_logdump(const char *signal) +{ + GDBusConnection *conn; + GError *error = NULL; + + LOGI("broadcast signal: %s", signal); + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error) { + LOGE("Failed to get dbus: %s", error->message); + g_error_free(error); + return -1; + } + + g_dbus_connection_emit_signal(conn, + NULL, + LOG_DUMP_OBJECT_PATH, + LOG_DUMP_INTERFACE_NAME, + signal, + NULL, + &error); + if (error) { + LOGE("Failed to emit signal: %s", error->message); + g_error_free(error); + return -1; + } + + return 0; +} + +int broadcast_logdump_start(void) +{ + return broadcast_logdump(LOG_DUMP_START_SIGNAL); +} + +int broadcast_logdump_finish(void) +{ + return broadcast_logdump(LOG_DUMP_FINISH_SIGNAL); +} diff --git a/src/log_dump/dbus-handler.h b/src/log_dump/dbus-handler.h index 0d3d5d9..a936f31 100644 --- a/src/log_dump/dbus-handler.h +++ b/src/log_dump/dbus-handler.h @@ -20,5 +20,7 @@ #define __LOGDUMP_DBUS_H__ int log_dump_dbus(void); +int broadcast_logdump_start(void); +int broadcast_logdump_finish(void); #endif diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c index 228112f..912aeef 100644 --- a/src/log_dump/log_dump.c +++ b/src/log_dump/log_dump.c @@ -94,6 +94,8 @@ int log_dump(int option) time_t cur_time; struct tm loc_tm; + broadcast_logdump_start(); + /* Make debug directory */ if (access(LOG_DUMP_DIR, F_OK) != 0) { ret = snprintf(command, sizeof(command), @@ -210,6 +212,8 @@ int log_dump(int option) } } + broadcast_logdump_finish(); + /* Further operations for log_dump here */ exit: -- 2.7.4 From 9f20f4b63f270dff7d4c92d27cab22489cdb8771 Mon Sep 17 00:00:00 2001 From: Kunhoon Baik Date: Wed, 30 Nov 2016 17:04:52 +0900 Subject: [PATCH 10/16] Disable New Crash Stack Change-Id: I3a7446f91e1d6289f8a37150c13669f058442685 --- src/crash-manager/crash-manager.sh.in | 12 ++++++------ src/sys-assert/sys-assert.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/crash-manager/crash-manager.sh.in b/src/crash-manager/crash-manager.sh.in index 7e1d607..882f0c3 100644 --- a/src/crash-manager/crash-manager.sh.in +++ b/src/crash-manager/crash-manager.sh.in @@ -43,18 +43,18 @@ tmp_callstack_path="${pfx}/${name}.callstack" sysassert_cs_path="/tmp/crash_stack/${cmd}_${pid}.info" mkdir -p "$pfx" +if [ "@SYS_ASSERT@" = "on" ] +then + mv "$sysassert_cs_path" "$pfx/" +fi if [ $DEBUG -eq 1 ] then - if [ "@SYS_ASSERT@" = "on" ] - then - mv "$sysassert_cs_path" "$pfx/" - fi @CRASH_PIPE_PATH@ --save-core "$core_path" --report "$@" > "$info_path" - @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" +# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" else @CRASH_PIPE_PATH@ --report "$@" > "$info_path" - @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" +# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" fi if [ -e $TZ_SYS_ETC/.debugmode ] diff --git a/src/sys-assert/sys-assert.c b/src/sys-assert/sys-assert.c index 0c1bbf2..5f8f30c 100644 --- a/src/sys-assert/sys-assert.c +++ b/src/sys-assert/sys-assert.c @@ -88,7 +88,7 @@ int sig_to_handle[] = { SIGILL, SIGTRAP, SIGABRT, SIGBUS, - SIGFPE, SIGSTKFLT, SIGXCPU, SIGXFSZ, SIGSYS }; + SIGFPE, SIGSEGV, SIGSTKFLT, SIGXCPU, SIGXFSZ, SIGSYS }; #define NUM_SIG_TO_HANDLE \ ((int)(sizeof(sig_to_handle)/sizeof(sig_to_handle[0]))) -- 2.7.4 From e36dea8248c101e63ec351d5f9d9c280505fb10b Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Fri, 2 Dec 2016 17:47:36 +0900 Subject: [PATCH 11/16] Upgrade: set RW update script number Change-Id: Ib8f40eaf90ee0d096de6f0191a367f458375bb09 --- packaging/crash-worker.spec | 2 +- .../{crash-manager-upgrade.sh.in => 500.crash-manager-upgrade.sh.in} | 0 src/crash-manager/CMakeLists.txt | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/crash-manager/{crash-manager-upgrade.sh.in => 500.crash-manager-upgrade.sh.in} (100%) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index b94edff..8b511ff 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -166,4 +166,4 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %endif #upgrade script -%attr(-,root,root) %{upgrade_script_path}/crash-manager-upgrade.sh +%attr(-,root,root) %{upgrade_script_path}/500.crash-manager-upgrade.sh diff --git a/src/crash-manager/crash-manager-upgrade.sh.in b/src/crash-manager/500.crash-manager-upgrade.sh.in similarity index 100% rename from src/crash-manager/crash-manager-upgrade.sh.in rename to src/crash-manager/500.crash-manager-upgrade.sh.in diff --git a/src/crash-manager/CMakeLists.txt b/src/crash-manager/CMakeLists.txt index 787934d..cf115ef 100644 --- a/src/crash-manager/CMakeLists.txt +++ b/src/crash-manager/CMakeLists.txt @@ -4,7 +4,7 @@ SET(CRASH_MANAGER "crash-manager") CONFIGURE_FILE(${CRASH_MANAGER}.sh.in ${CRASH_MANAGER}.sh @ONLY) CONFIGURE_FILE(99-${CRASH_MANAGER}.conf.in 99-${CRASH_MANAGER}.conf @ONLY) -CONFIGURE_FILE(${CRASH_MANAGER}-upgrade.sh.in ${CRASH_MANAGER}-upgrade.sh @ONLY) +CONFIGURE_FILE(500.${CRASH_MANAGER}-upgrade.sh.in 500.${CRASH_MANAGER}-upgrade.sh @ONLY) INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/${CRASH_MANAGER}.sh DESTINATION ${TZ_SYS_BIN} @@ -15,7 +15,7 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/99-${CRASH_MANAGER}.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/sysctl.d PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/${CRASH_MANAGER}-upgrade.sh +INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/500.${CRASH_MANAGER}-upgrade.sh DESTINATION ${UPGRADE_SCRIPT_PATH} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -- 2.7.4 From 7be4966ac4a0ca03b68ded0b9b883a0f7bc568f1 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Fri, 2 Dec 2016 18:25:08 +0900 Subject: [PATCH 12/16] dump_systemstate: extend sort buffer size Dump info needs to have enough information. So set the buffer size of dlogutil larger than default. Change-Id: I999caa73c130649fd75449b7ace400f683abfc89 --- src/dump_systemstate/dump_systemstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dump_systemstate/dump_systemstate.c b/src/dump_systemstate/dump_systemstate.c index aed09b6..0359a6a 100644 --- a/src/dump_systemstate/dump_systemstate.c +++ b/src/dump_systemstate/dump_systemstate.c @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) if (arg_dlog) { fprintf_fd(out_fd, "\n==== Log messages\n"); - ret = run_command_write_fd("/usr/bin/dlogutil -d -v threadtime", out_fd); + ret = run_command_write_fd("/usr/bin/dlogutil -d -v threadtime -u 16384", out_fd); if (ret < 0) goto exit_close; } -- 2.7.4 From 0b4d07401375ca142782fe9001eef196b0ecf0d7 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Mon, 5 Dec 2016 16:59:22 +0900 Subject: [PATCH 13/16] Rearrange crash-manager tasks Launching crash popup and collecting log are required to be done first. Change-Id: I97d48117223fffc7c61923c742062f16b4f288eb --- src/crash-manager/99-crash-manager.conf.in | 2 +- src/crash-manager/crash-manager.sh.in | 38 +++++++++--------------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/crash-manager/99-crash-manager.conf.in b/src/crash-manager/99-crash-manager.conf.in index 8277deb..505bc20 100644 --- a/src/crash-manager/99-crash-manager.conf.in +++ b/src/crash-manager/99-crash-manager.conf.in @@ -1,3 +1,3 @@ # Tizen crash-manager -kernel.core_pattern=|/usr/bin/crash-manager.sh %p %u %g %s %t %e +kernel.core_pattern=|/usr/bin/crash-manager.sh %p %u %g %s %t %e %E kernel.core_pipe_limit=10 diff --git a/src/crash-manager/crash-manager.sh.in b/src/crash-manager/crash-manager.sh.in index 882f0c3..93e1e6a 100644 --- a/src/crash-manager/crash-manager.sh.in +++ b/src/crash-manager/crash-manager.sh.in @@ -26,7 +26,7 @@ DEBUG=1 # Expected invocation from kernel: # -# argv0 PID UID GID SIGNAL TIME CMD +# argv0 PID UID GID SIGNAL TIME CMD EXEPATH pid="$1" time="$5" cmd="$6" @@ -48,34 +48,10 @@ then mv "$sysassert_cs_path" "$pfx/" fi -if [ $DEBUG -eq 1 ] -then - @CRASH_PIPE_PATH@ --save-core "$core_path" --report "$@" > "$info_path" -# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" -else - @CRASH_PIPE_PATH@ --report "$@" > "$info_path" -# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" -fi - if [ -e $TZ_SYS_ETC/.debugmode ] then #Find the full path of executable. The path is used to find appid in the crash-popup - exepath=" " - found=0 - while read line - do - if [ $found -eq 1 ] - then - exepath=$(echo $line | sed "s/0: //") - break - fi - - if [ "$line" = "Cmdline:" ] - then - found=1 - fi - - done < $info_path + exepath="$(echo $7 | sed 's/!/\//g')" #Call dbus method to launch the crash-popup /usr/bin/dbus-send --system --type=method_call --print-reply --reply-timeout=120000 --dest=org.tizen.system.popup /Org/Tizen/System/Popup/Crash org.tizen.system.popup.Crash.PopupLaunch dict:string:string:"_SYSPOPUP_CONTENT_","crash","_PROCESS_NAME_","${cmd}","_EXEPATH_","${exepath}" @@ -84,8 +60,16 @@ fi dump_systemstate -d -k -f "$log_path" || true +if [ $DEBUG -eq 1 ] +then + @CRASH_PIPE_PATH@ --save-core "$core_path" --report "$@" > "$info_path" +# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" +else + @CRASH_PIPE_PATH@ --report "$@" > "$info_path" +# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" +fi + tar czf "${temp_dir}/report.tar.gz" -C "$temp_dir" "$name" mv "${temp_dir}/report.tar.gz" "$result_path" [ "$temp_dir" ] && rm -rf "$temp_dir" - -- 2.7.4 From 3a9ae31e611388f8c1e10ec49a25010c9b09636b Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Fri, 11 Nov 2016 11:01:27 +0900 Subject: [PATCH 14/16] Convert crash-manager into c code For ease of adding features, crash-manager is converted to c code. * Minor changes - unused library headers removed (log_dump) - change date format (epoch -> local) Change-Id: I6f27547469769b2ba3c01027cf53bc0d17d82c5e Signed-off-by: Sunmin Lee --- packaging/crash-worker.manifest | 2 +- packaging/crash-worker.spec | 7 +- src/crash-manager/99-crash-manager.conf.in | 2 +- src/crash-manager/CMakeLists.txt | 37 ++- src/crash-manager/crash-manager.c | 412 +++++++++++++++++++++++++++++ src/crash-manager/crash-manager.h.in | 31 +++ src/crash-manager/crash-manager.sh.in | 75 ------ src/log_dump/CMakeLists.txt | 1 - src/log_dump/dbus-handler.c | 1 - 9 files changed, 478 insertions(+), 90 deletions(-) create mode 100644 src/crash-manager/crash-manager.c create mode 100644 src/crash-manager/crash-manager.h.in delete mode 100644 src/crash-manager/crash-manager.sh.in diff --git a/packaging/crash-worker.manifest b/packaging/crash-worker.manifest index 61052fb..8e0f4fd 100644 --- a/packaging/crash-worker.manifest +++ b/packaging/crash-worker.manifest @@ -4,6 +4,6 @@ - + diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 8b511ff..2d7c68f 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -9,6 +9,7 @@ License: Apache-2.0 and PD Source0: %{name}-%{version}.tar.gz Source1001: crash-worker.manifest BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(glib-2.0) @@ -82,7 +83,9 @@ export CFLAGS+=" -Werror" -DCRASH_TEMP=%{crash_temp} \ -DCRASH_PIPE_PATH=%{_libexecdir}/crash-pipe \ -DCRASH_STACK_PATH=%{_libexecdir}/crash-stack \ +%if "%{?sys_assert}" == "on" -DSYS_ASSERT=%{sys_assert} \ +%endif -DUPGRADE_SCRIPT_PATH=%{upgrade_script_path} # to add support for core dump files add backslash at the end of above line # and uncomment below line: @@ -145,9 +148,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %dir %{crash_temp} %dir %{crash_all_log} %{crash_dump_gen}/* -%attr(0755,system,system) %{_bindir}/dump_systemstate -%attr(0755,system,system) %{_bindir}/crash-manager.sh -%attr(0755,system,system) %{_bindir}/log_dump +%attr(0755,root,root) %{_bindir}/* %attr(0644,root,system) %{_unitdir}/tizen-debug-on.service %attr(0644,root,system) %{_unitdir}/tizen-debug-off.service %{_prefix}/lib/sysctl.d/99-crash-manager.conf diff --git a/src/crash-manager/99-crash-manager.conf.in b/src/crash-manager/99-crash-manager.conf.in index 505bc20..481362f 100644 --- a/src/crash-manager/99-crash-manager.conf.in +++ b/src/crash-manager/99-crash-manager.conf.in @@ -1,3 +1,3 @@ # Tizen crash-manager -kernel.core_pattern=|/usr/bin/crash-manager.sh %p %u %g %s %t %e %E +kernel.core_pattern=|/usr/bin/crash-manager %p %u %g %s %t %e %E kernel.core_pipe_limit=10 diff --git a/src/crash-manager/CMakeLists.txt b/src/crash-manager/CMakeLists.txt index cf115ef..23f7570 100644 --- a/src/crash-manager/CMakeLists.txt +++ b/src/crash-manager/CMakeLists.txt @@ -1,21 +1,42 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(crash-manager C) -SET(CRASH_MANAGER "crash-manager") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) +SET(CRASH_MANAGER_SRCS + crash-manager.c + ${CMAKE_SOURCE_DIR}/src/shared/util.c + ) -CONFIGURE_FILE(${CRASH_MANAGER}.sh.in ${CRASH_MANAGER}.sh @ONLY) -CONFIGURE_FILE(99-${CRASH_MANAGER}.conf.in 99-${CRASH_MANAGER}.conf @ONLY) -CONFIGURE_FILE(500.${CRASH_MANAGER}-upgrade.sh.in 500.${CRASH_MANAGER}-upgrade.sh @ONLY) +INCLUDE(FindPkgConfig) +pkg_check_modules(crash-manager_pkgs REQUIRED + dlog + libsmack + libtzplatform-config + gio-2.0 + ) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/${CRASH_MANAGER}.sh - DESTINATION ${TZ_SYS_BIN} +FOREACH(flag ${crash-manager_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") + +CONFIGURE_FILE(crash-manager.h.in crash-manager.h @ONLY) +ADD_EXECUTABLE(${PROJECT_NAME} ${CRASH_MANAGER_SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/99-${CRASH_MANAGER}.conf +CONFIGURE_FILE(99-${PROJECT_NAME}.conf.in 99-${PROJECT_NAME}.conf @ONLY) +CONFIGURE_FILE(500.${PROJECT_NAME}-upgrade.sh.in 500.${PROJECT_NAME}-upgrade.sh @ONLY) + +INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/99-${PROJECT_NAME}.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/sysctl.d PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${CRASH_MANAGER}/500.${CRASH_MANAGER}-upgrade.sh +INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/500.${PROJECT_NAME}-upgrade.sh DESTINATION ${UPGRADE_SCRIPT_PATH} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c new file mode 100644 index 0000000..35f8fb6 --- /dev/null +++ b/src/crash-manager/crash-manager.c @@ -0,0 +1,412 @@ +/* + * crash-manager + * + * Copyright (c) 2016 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crash-manager.h" +#include "shared/util.h" + +#undef LOG_TAG +#define LOG_TAG "CRASH_MANAGER" + +#define DEBUGMODE_FILE tzplatform_mkpath(TZ_SYS_ETC, ".debugmode") + +/* Crash-popup dbus */ +#define POPUP_BUS_NAME "org.tizen.system.popup" +#define POPUP_OBJECT_PATH "/Org/Tizen/System/Popup/Crash" +#define POPUP_INTERFACE_NAME POPUP_BUS_NAME".Crash" +#define POPUP_METHOD "PopupLaunch" + +/* Paths and variables */ +static struct crash_info { + char *cmd_info; + char *pid_info; + char time_info[80]; + char temp_dir[PATH_MAX]; + char name[FILENAME_MAX]; + char result_path[PATH_MAX]; + char pfx[PATH_MAX]; + char info_path[PATH_MAX]; + char core_path[PATH_MAX]; + char log_path[PATH_MAX]; +#ifdef SYS_ASSERT + char sysassert_cs_path[PATH_MAX]; +#endif +} crash_info; + +static int make_dump_dir(void) +{ + struct stat st; + + if (!stat(CRASH_PATH, &st)) { + if (!(st.st_mode & S_IFDIR)) { + LOGE("%s (not DIR) is already exist", CRASH_PATH); + return -1; + } + } else { + if (mkdir(CRASH_PATH, 0775) < 0) { + LOGE("Failed to mkdir for %s", CRASH_PATH); + return -1; + } + smack_setlabel(CRASH_PATH, "System::Shared", + SMACK_LABEL_ACCESS); + smack_setlabel(CRASH_PATH, "1", SMACK_LABEL_TRANSMUTE); + } + + if (!stat(CRASH_TEMP, &st)) { + if (!(st.st_mode & S_IFDIR)) { + LOGE("%s (not DIR) is already exist", CRASH_TEMP); + return -1; + } + } else { + if (mkdir(CRASH_TEMP, 0775) < 0) { + LOGE("Failed to mkdir for %s", CRASH_TEMP); + return -1; + } + smack_setlabel(CRASH_TEMP, "System::Shared", + SMACK_LABEL_ACCESS); + smack_setlabel(CRASH_TEMP, "1", SMACK_LABEL_TRANSMUTE); + } + + return 0; +} + +static int set_crash_info(char *argv[]) +{ + int ret; + char *temp_dir_ret; + time_t time_val; + struct tm loc_tm; + + crash_info.cmd_info = argv[6]; + crash_info.pid_info = argv[1]; + + time_val = atoll(argv[5]); + localtime_r(&time_val, &loc_tm); + strftime(crash_info.time_info, sizeof(crash_info.time_info), + "%Y%m%d%H%M%S", &loc_tm); + + ret = snprintf(crash_info.temp_dir, sizeof(crash_info.temp_dir), + "%s/crash.XXXXXX", CRASH_TEMP); + if (ret < 0) { + LOGE("Failed to snprintf for temp_dir"); + return -1; + } + temp_dir_ret = mkdtemp(crash_info.temp_dir); + if (access(temp_dir_ret, F_OK)) { + LOGE("Failed to mkdtemp for temp_dir"); + return -1; + } + + ret = snprintf(crash_info.name, sizeof(crash_info.name), "%s_%s_%s", + crash_info.cmd_info, + crash_info.pid_info, + crash_info.time_info); + if (ret < 0) { + LOGE("Failed to snprintf for name"); + goto rm_temp; + } + + ret = snprintf(crash_info.result_path, sizeof(crash_info.result_path), + "%s/%s.tar.gz", CRASH_PATH, crash_info.name); + if (ret < 0) { + LOGE("Failed to snprintf for result path"); + goto rm_temp; + } + + ret = snprintf(crash_info.pfx, sizeof(crash_info.pfx), "%s/%s", + crash_info.temp_dir, crash_info.name); + if (ret < 0) { + LOGE("Failed to snprintf for pfx"); + goto rm_temp; + } + ret = mkdir(crash_info.pfx, 0775); + if (ret < 0) { + LOGE("Failed to mkdir for %s", crash_info.pfx); + goto rm_temp; + } + + ret = snprintf(crash_info.info_path, sizeof(crash_info.info_path), + "%s/%s.info", crash_info.pfx, crash_info.name); + if (ret < 0) { + LOGE("Failed to snprintf for info path"); + goto rm_temp; + } + + ret = snprintf(crash_info.core_path, sizeof(crash_info.core_path), + "%s/%s.coredump", crash_info.pfx, crash_info.name); + if (ret < 0) { + LOGE("Failed to snprintf for core path"); + goto rm_temp; + } + + ret = snprintf(crash_info.log_path, sizeof(crash_info.log_path), + "%s/%s.log", crash_info.pfx, crash_info.name); + if (ret < 0) { + LOGE("Failed to snprintf for log path"); + goto rm_temp; + } + +#ifdef SYS_ASSERT + ret = snprintf(crash_info.sysassert_cs_path, + sizeof(crash_info.sysassert_cs_path), + "/tmp/crash_stack/%s_%s.info", + crash_info.cmd_info, crash_info.pid_info); + if (ret < 0) { + LOGE("Failed to snprintf for sys-assert callstack path"); + goto rm_temp; + } +#endif + + return 0; + +rm_temp: + remove_dir(crash_info.temp_dir, 1); + return -1; +} + +#ifdef SYS_ASSERT +static int get_sysassert_cs(void) +{ + int ret; + char move_path[PATH_MAX]; + + if (access(crash_info.sysassert_cs_path, F_OK)) { + LOGE("The sys-assert cs file not found: %s", + crash_info.sysassert_cs_path); + return -1; + } + + ret = snprintf(move_path, sizeof(move_path), "%s/%s", + crash_info.pfx, basename(crash_info.sysassert_cs_path)); + if (ret < 0) { + LOGE("Failed to snprintf for move path"); + return -1; + } + + if (move_file(crash_info.sysassert_cs_path, move_path) < 0) { + LOGE("Failed to move %s to %s", + crash_info.sysassert_cs_path, move_path); + return -1; + } + + return 0; +} +#endif + +static int convert_path(char *path, char *core_exepath) +{ + int i; + + for (i = 0; core_exepath[i]; i++) + path[i] = (core_exepath[i] == '!' ? '/' : core_exepath[i]); + path[i] = '\0'; + + return i; +} + +static void launch_crash_popup(char *core_exepath) +{ + GDBusConnection *conn; + GVariantBuilder *builder; + GVariant *parameters = NULL; + GVariant *reply = NULL; + GError *error = NULL; + int ret; + char exepath[PATH_MAX] = "\0"; + + if (convert_path(exepath, core_exepath) <= 0) { + LOGE("Failed to parsing exepath"); + return; + } + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error) { + LOGE("Failed to get dbus: %s", error->message); + g_error_free(error); + return; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add(builder, "{ss}", "_SYSPOPUP_CONTENT_", "crash"); + g_variant_builder_add(builder, "{ss}", "_PROCESS_NAME_", + crash_info.cmd_info); + g_variant_builder_add(builder, "{ss}", "_EXEPATH_", exepath); + parameters = g_variant_new("(a{ss})", builder); + g_variant_builder_unref(builder); + + reply = g_dbus_connection_call_sync(conn, + POPUP_BUS_NAME, + POPUP_OBJECT_PATH, + POPUP_INTERFACE_NAME, + POPUP_METHOD, + parameters, + G_VARIANT_TYPE("(i)"), + G_DBUS_CALL_FLAGS_NONE, + 120000, + NULL, + &error); + if (error) { + LOGE("Failed to get reply: %s", error->message); + g_error_free(error); + goto exit; + } + + g_variant_get(reply, "(i)", &ret); + LOGI("Crash_popup is launched: (%d)", ret); + +exit: + if (reply) + g_variant_unref(reply); + if (parameters) + g_variant_unref(parameters); +} + +static void dump_system_state(void) +{ + int ret; + char command[PATH_MAX]; + + ret = snprintf(command, sizeof(command), + "/usr/bin/dump_systemstate -d -k -f %s", + crash_info.log_path); + if (ret < 0) { + LOGE("Failed to snprintf for dump_systemstate command"); + return; + } + system_command(command); +} + +static void execute_crash_modules(int argc, char *argv[], int debug) +{ + int ret, i; + char arg_append[PATH_MAX]; + char command[PATH_MAX]; + + arg_append[0] = '\0'; + for (i = 1; i < argc; i++) { + strcat(arg_append, argv[i]); + strcat(arg_append, " "); + } + + /* Execute crash-pipe */ + if (debug) + ret = snprintf(command, sizeof(command), + "%s --save-core %s --report %s > %s", + CRASH_PIPE_PATH, + crash_info.core_path, arg_append, + crash_info.info_path); + else + ret = snprintf(command, sizeof(command), + "%s --report %s > %s", + CRASH_PIPE_PATH, + arg_append, + crash_info.info_path); + if (ret < 0) { + LOGE("Failed to snprintf for crash-pipe command"); + return; + } + system_command(command); + + /* Execute crash-stack */ + /* + ret = snprintf(command, sizeof(command), + "%s --pid %s >> %s", + CRASH_STACK_PATH, + crash_info.pid_info, crash_info.info_path); + if (ret < 0) { + LOGE("Failed to snprintf for crash-stack command"); + return; + } + system_command(command); + */ +} + +static void compress(void) +{ + int ret; + char tar_path[PATH_MAX]; + char command[PATH_MAX]; + + ret = snprintf(tar_path, sizeof(tar_path), "%s/report.tar.gz", + crash_info.temp_dir); + if (ret < 0) { + LOGE("Failed to snprintf for tar path"); + return; + } + + ret = snprintf(command, sizeof(command), + "/bin/tar -czf %s -C %s %s", + tar_path, crash_info.temp_dir, crash_info.name); + if (ret < 0) { + LOGE("Failed to snprintf for tar command"); + return; + } + system_command(command); + + if (move_file(tar_path, crash_info.result_path) < 0) + LOGE("Failed to move %s to %s", + tar_path, crash_info.result_path); + + ret = remove_dir(crash_info.temp_dir, 1); + if (ret < 0) + LOGE("Failed to delete temp directory"); +} + +int main(int argc, char *argv[]) +{ + prctl(PR_SET_DUMPABLE, 0); + + /* Create crash directories */ + if (make_dump_dir() < 0) + exit(EXIT_FAILURE); + + /* Set crash info */ + if (set_crash_info(argv) < 0) + exit(EXIT_FAILURE); + +#ifdef SYS_ASSERT + /* Fetch callstack of sys-assert */ + get_sysassert_cs(); +#endif + + /* .dbugmode: launch crash-popup */ + if (access(DEBUGMODE_FILE, F_OK) == 0) + launch_crash_popup(argv[7]); + + /* Exec dump_systemstate */ + dump_system_state(); + + /* Exec crash modules */ + execute_crash_modules(argc, argv, DEBUG); + + /* Tar compression */ + compress(); + + return 0; +} diff --git a/src/crash-manager/crash-manager.h.in b/src/crash-manager/crash-manager.h.in new file mode 100644 index 0000000..90de995 --- /dev/null +++ b/src/crash-manager/crash-manager.h.in @@ -0,0 +1,31 @@ +/* + * crash-manager + * + * Copyright (c) 2016 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 __CRASH_MANAGER_H__ +#define __CRASH_MANAGER_H__ + +/* Make build variables to string */ +#define CRASH_PATH "@CRASH_PATH@" +#define CRASH_TEMP "@CRASH_TEMP@" +#define SYS_ASSERT "@SYS_ASSERT@" +#define CRASH_STACK_PATH "@CRASH_STACK_PATH@" +#define CRASH_PIPE_PATH "@CRASH_PIPE_PATH@" + +#define DEBUG 1 + +#endif diff --git a/src/crash-manager/crash-manager.sh.in b/src/crash-manager/crash-manager.sh.in deleted file mode 100644 index 93e1e6a..0000000 --- a/src/crash-manager/crash-manager.sh.in +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh - -source /etc/tizen-platform.conf - -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -exec >/dev/null 2>&1 - -PATH=/bin:/usr/bin -CRASH_PATH="@CRASH_PATH@" -CRASH_TEMP="@CRASH_TEMP@" - -if [ ! -d "${CRASH_PATH}" ] -then - mkdir -p "${CRASH_PATH}" - /usr/bin/chsmack -a "System::Shared" -t "${CRASH_PATH}" -fi - -if [ ! -d "${CRASH_TEMP}" ] -then - mkdir -p "${CRASH_TEMP}" - /usr/bin/chsmack -a "System::Shared" -t "${CRASH_TEMP}" -fi - -DEBUG=1 - -# Expected invocation from kernel: -# -# argv0 PID UID GID SIGNAL TIME CMD EXEPATH -pid="$1" -time="$5" -cmd="$6" - -temp_dir="$(mktemp -d "${CRASH_TEMP}/crash.XXXXXX")" - -name="${cmd}_${pid}_${time}" -result_path="${CRASH_PATH}/${name}.tar.gz" -pfx="${temp_dir}/${name}" -info_path="${pfx}/${name}.info" -core_path="${pfx}/${name}.coredump" -log_path="${pfx}/${name}.log" -tmp_callstack_path="${pfx}/${name}.callstack" -sysassert_cs_path="/tmp/crash_stack/${cmd}_${pid}.info" - -mkdir -p "$pfx" -if [ "@SYS_ASSERT@" = "on" ] -then - mv "$sysassert_cs_path" "$pfx/" -fi - -if [ -e $TZ_SYS_ETC/.debugmode ] -then -#Find the full path of executable. The path is used to find appid in the crash-popup - exepath="$(echo $7 | sed 's/!/\//g')" - -#Call dbus method to launch the crash-popup - /usr/bin/dbus-send --system --type=method_call --print-reply --reply-timeout=120000 --dest=org.tizen.system.popup /Org/Tizen/System/Popup/Crash org.tizen.system.popup.Crash.PopupLaunch dict:string:string:"_SYSPOPUP_CONTENT_","crash","_PROCESS_NAME_","${cmd}","_EXEPATH_","${exepath}" - -fi - -dump_systemstate -d -k -f "$log_path" || true - -if [ $DEBUG -eq 1 ] -then - @CRASH_PIPE_PATH@ --save-core "$core_path" --report "$@" > "$info_path" -# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" -else - @CRASH_PIPE_PATH@ --report "$@" > "$info_path" -# @CRASH_STACK_PATH@ --pid "$pid" >> "$info_path" -fi - -tar czf "${temp_dir}/report.tar.gz" -C "$temp_dir" "$name" -mv "${temp_dir}/report.tar.gz" "$result_path" - -[ "$temp_dir" ] && rm -rf "$temp_dir" diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt index 1d6d220..7fa6891 100644 --- a/src/log_dump/CMakeLists.txt +++ b/src/log_dump/CMakeLists.txt @@ -13,7 +13,6 @@ pkg_check_modules(log_dump_pkgs REQUIRED dlog capi-system-info libtzplatform-config - glib-2.0 gio-2.0 ) diff --git a/src/log_dump/dbus-handler.c b/src/log_dump/dbus-handler.c index 16274cb..f283c40 100644 --- a/src/log_dump/dbus-handler.c +++ b/src/log_dump/dbus-handler.c @@ -17,7 +17,6 @@ */ #include -#include #include #include "log_dump.h" #include "dbus-handler.h" -- 2.7.4 From 55c8b13d931481ceac3f0e5c866926e139fb1c28 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Fri, 18 Nov 2016 11:20:20 +0900 Subject: [PATCH 15/16] Configurable crash-manager crash-manager can manage dump output according to configured value in config file (crash-manager.conf). The config values SystemMaxUse : The maximum usage of partition that crash dump can be generated SystemKeepFree : The free space should be kept MaxRetentionSec: The retention time of each dump file MaxCrashDump : The maximum number of dump file to be preserved AllowZip : Whether compressing dump or not Change-Id: Ib0c3cd9445338e469040b07aebf81bf6705fd29e Signed-off-by: Sunmin Lee --- packaging/crash-worker.spec | 5 +- src/crash-manager/CMakeLists.txt | 5 + src/crash-manager/crash-manager.c | 397 ++++++++++++++++++++++++++++++++++- src/crash-manager/crash-manager.conf | 6 + src/shared/util.c | 6 +- 5 files changed, 409 insertions(+), 10 deletions(-) create mode 100644 src/crash-manager/crash-manager.conf diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 2d7c68f..7e11142 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -11,6 +11,7 @@ Source1001: crash-worker.manifest BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(iniparser) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(glib-2.0) BuildRequires: cmake @@ -77,6 +78,7 @@ export CFLAGS+=" -Werror" -DTMP_FILES_DIR=%{_sysconfdir}/tmpfiles.d \ -DARCH=%{ARCH} \ -DARCH_BIT=%{ARCH_BIT} \ + -DTZ_SYS_ETC=%{TZ_SYS_ETC} \ -DTZ_SYS_BIN=%{TZ_SYS_BIN} \ -DCRASH_ROOT_PATH=%{crash_root_path} \ -DCRASH_PATH=%{crash_path} \ @@ -129,7 +131,7 @@ fi /usr/bin/chsmack -a "System::Shared" -t %{crash_temp} /usr/bin/chsmack -a "System::Shared" -t %{crash_dump_gen} /usr/bin/chsmack -a "System::Shared" -t %{crash_dump_gen}/module.d -/usr/bin/chsmack -d %{crash_dump_gen}/module.d/* +/usr/bin/chsmack -a "_" %{crash_dump_gen}/module.d/* %postun %if "%{?sys_assert}" == "on" @@ -151,6 +153,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %attr(0755,root,root) %{_bindir}/* %attr(0644,root,system) %{_unitdir}/tizen-debug-on.service %attr(0644,root,system) %{_unitdir}/tizen-debug-off.service +%{TZ_SYS_ETC}/crash-manager.conf %{_prefix}/lib/sysctl.d/99-crash-manager.conf %{_datadir}/dbus-1/system-services/org.tizen.system.crash.service diff --git a/src/crash-manager/CMakeLists.txt b/src/crash-manager/CMakeLists.txt index 23f7570..361ac34 100644 --- a/src/crash-manager/CMakeLists.txt +++ b/src/crash-manager/CMakeLists.txt @@ -12,6 +12,7 @@ pkg_check_modules(crash-manager_pkgs REQUIRED dlog libsmack libtzplatform-config + iniparser gio-2.0 ) @@ -32,6 +33,10 @@ INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin CONFIGURE_FILE(99-${PROJECT_NAME}.conf.in 99-${PROJECT_NAME}.conf @ONLY) CONFIGURE_FILE(500.${PROJECT_NAME}-upgrade.sh.in 500.${PROJECT_NAME}-upgrade.sh @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.conf + DESTINATION ${TZ_SYS_ETC} + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) + INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/99-${PROJECT_NAME}.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/sysctl.d PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 35f8fb6..d0142df 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -16,16 +16,22 @@ * limitations under the License. */ +#define _GNU_SOURCE + #include #include +#include #include #include #include +#include #include #include #include #include +#include #include +#include #include #include #include "crash-manager.h" @@ -34,7 +40,14 @@ #undef LOG_TAG #define LOG_TAG "CRASH_MANAGER" -#define DEBUGMODE_FILE tzplatform_mkpath(TZ_SYS_ETC, ".debugmode") +#define DEBUGMODE_FILE tzplatform_mkpath(TZ_SYS_ETC, ".debugmode") +#define LOCK_FILE CRASH_PATH"/.lock" +#define LOCK_FILE_VALIDITY 10 + +/* Parsing */ +#define CRASH_CONF_FILE tzplatform_mkpath(TZ_SYS_ETC, "crash-manager.conf") +#define KEY_MAX 255 +#define CRASH_SECTION "CrashManager" /* Crash-popup dbus */ #define POPUP_BUS_NAME "org.tizen.system.popup" @@ -42,6 +55,29 @@ #define POPUP_INTERFACE_NAME POPUP_BUS_NAME".Crash" #define POPUP_METHOD "PopupLaunch" +/* Configuration default values */ +#define SYSTEM_MAX_USE 10240 +#define SYSTEM_KEEP_FREE 0 +#define MAX_RETENTION_SEC 1296000 +#define MAX_CRASH_DUMP 5 +#define ALLOW_ZIP true + +#define CRASH_CHECK_DISK_PATH "/opt/usr" + +struct file_info { + bool isdir; + int size; + time_t mtime; + char *path; +}; + +/* Configuration variables */ +static int system_max_use; +static int system_keep_free; +static int max_retention_sec; +static int max_crash_dump; +static bool allow_zip; + /* Paths and variables */ static struct crash_info { char *cmd_info; @@ -59,6 +95,78 @@ static struct crash_info { #endif } crash_info; +static void get_config(void) +{ + dictionary *ini = NULL; + char key[KEY_MAX]; + int value; + + system_max_use = SYSTEM_MAX_USE; + system_keep_free = SYSTEM_KEEP_FREE; + max_retention_sec = MAX_RETENTION_SEC; + max_crash_dump = MAX_CRASH_DUMP; + allow_zip = ALLOW_ZIP; + + ini = iniparser_load(CRASH_CONF_FILE); + if (!ini) { + LOGE("Failed to load conf file"); + return; + } + + snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "SystemMaxUse"); + value = iniparser_getint(ini, key, -1); + if (value < 0) { + LOGD("Invalid value for SystemMaxUse. Use default value [ %d kbyte]", + SYSTEM_MAX_USE); + } else { + LOGD("SystemMaxUse [ %d kbyte]", value); + system_max_use = value; + } + + snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "SystemKeepFree"); + value = iniparser_getint(ini, key, -1); + if (value < 0) { + LOGD("Invalid value for SystemKeepFree. Use default value [ %d kbyte]", + SYSTEM_KEEP_FREE); + } else { + LOGD("SystemKeepFree [ %d kbyte]", value); + system_keep_free = value; + } + + + snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "MaxRetentionSec"); + value = iniparser_getint(ini, key, -1); + if (value < 0) { + LOGD("Invalid value for MaxRetentionSec. Use default value [ %d ]", + MAX_RETENTION_SEC); + } else { + LOGD("MaxRetentionSec [ %d ]", value); + max_retention_sec = value; + } + + snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "MaxCrashDump"); + value = iniparser_getint(ini, key, -1); + if (value < 0) { + LOGD("Invalid value for MaxCrashDump. Use default value [ %d ]", + MAX_CRASH_DUMP); + } else { + LOGD("MaxCrashDump [ %d ]", value); + max_crash_dump = value; + } + + snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "AllowZip"); + value = iniparser_getboolean(ini, key, -1); + if (value < 0) { + LOGD("Invalid value for AllowZip. Use default value [ %s ]", + ALLOW_ZIP ? "true" : "false" ); + } else { + LOGD("AllowZip [ %s ]", value ? "true" : "false"); + allow_zip = value; + } + + iniparser_freedict(ini); +} + static int make_dump_dir(void) { struct stat st; @@ -132,8 +240,14 @@ static int set_crash_info(char *argv[]) goto rm_temp; } - ret = snprintf(crash_info.result_path, sizeof(crash_info.result_path), - "%s/%s.tar.gz", CRASH_PATH, crash_info.name); + if (allow_zip) + ret = snprintf(crash_info.result_path, + sizeof(crash_info.result_path), + "%s/%s.tar.gz", CRASH_PATH, crash_info.name); + else + ret = snprintf(crash_info.result_path, + sizeof(crash_info.result_path), + "%s/%s", CRASH_PATH, crash_info.name); if (ret < 0) { LOGE("Failed to snprintf for result path"); goto rm_temp; @@ -347,6 +461,36 @@ static void execute_crash_modules(int argc, char *argv[], int debug) */ } +static void dump_lock(void) +{ + struct stat st; + time_t cur_time; + int fd; + + while ((fd = open(LOCK_FILE, O_CREAT | O_EXCL, 0644)) < 0) { + if (stat(LOCK_FILE, &st) < 0) { + LOGE("Failed to stat lock file"); + return; + } + + cur_time = time(NULL); + if (st.st_mtime + LOCK_FILE_VALIDITY < cur_time) { + LOGI("Lock file validity over"); + if (unlink(LOCK_FILE) < 0) + LOGE("Failed to unlink %s", LOCK_FILE); + return; + } + sleep(LOCK_FILE_VALIDITY / 2); + } + close(fd); +} + +static void dump_unlock(void) +{ + if (unlink(LOCK_FILE) < 0) + LOGE("Failed to unlink %s", LOCK_FILE); +} + static void compress(void) { int ret; @@ -369,19 +513,256 @@ static void compress(void) } system_command(command); - if (move_file(tar_path, crash_info.result_path) < 0) + dump_lock(); + if (rename(tar_path, crash_info.result_path) < 0) LOGE("Failed to move %s to %s", tar_path, crash_info.result_path); + dump_unlock(); ret = remove_dir(crash_info.temp_dir, 1); if (ret < 0) LOGE("Failed to delete temp directory"); } +static void move_dump_dir(void) +{ + int ret; + + dump_lock(); + ret = rename(crash_info.pfx, crash_info.result_path); + dump_unlock(); + if (ret < 0) { + LOGE("Failed to move %s to %s", + crash_info.pfx, crash_info.result_path); + return; + } + + ret = remove_dir(crash_info.temp_dir, 1); + if (ret < 0) + LOGE("Failed to delete temp directory"); +} + +static int dump_filter(const struct dirent *de) +{ + if (de->d_name[0] == '.') + return 0; + return 1; +} + +static int mtime_cmp(const void *_a, const void *_b) +{ + const struct file_info *a = _a; + const struct file_info *b = _b; + + if (a->mtime < b->mtime) + return -1; + if (a->mtime > b->mtime) + return 1; + return 0; +} + +static int scan_dump(struct file_info **dump_list) +{ + struct file_info *temp_list; + struct dirent **scan_list = NULL; + struct stat st; + int i, scan_num, dump_num = 0; + int fd; + + if ((fd = open(CRASH_PATH, O_DIRECTORY)) < 0 ) { + LOGE("Failed to open %s", CRASH_PATH); + return -1; + } + + scan_num = scandir(CRASH_PATH, &scan_list, &dump_filter, NULL); + if (scan_num < 0) { + close(fd); + return -1; + } + + temp_list = (struct file_info *)calloc(scan_num, + sizeof(struct file_info)); + if (!temp_list) { + LOGE("Failed to calloc for dump list"); + goto exit; + } + + for (i = 0; i < scan_num; i++) { + if (fstatat(fd, scan_list[i]->d_name, &st, 0) < 0) { + LOGE("Failed to fstatat"); + continue; + } + + if (asprintf(&(temp_list[dump_num].path), "%s/%s", + CRASH_PATH, scan_list[i]->d_name) < 0) { + LOGE("Failed to asprintf"); + continue; + } + + if (scan_list[i]->d_type == DT_DIR) { + temp_list[dump_num].isdir = 1; + temp_list[dump_num].size = + get_directory_usage(temp_list[dump_num].path); + } else { + temp_list[dump_num].isdir = 0; + temp_list[dump_num].size = st.st_size; + } + temp_list[dump_num].mtime = st.st_mtime; + dump_num++; + } + + if (dump_num <= 0) { + free(temp_list); + goto exit; + } + + if (dump_num != scan_num) + temp_list = (struct file_info *)realloc(temp_list, + dump_num * sizeof(struct file_info)); + + qsort(temp_list, dump_num, sizeof(struct file_info), mtime_cmp); + + for (i = 0; i < dump_num; i++) + LOGD("[%d] path: %s(%s), size: %d kb, mtime: %s", + i, + temp_list[i].path, + temp_list[i].isdir ? "DIR" : "FILE", + temp_list[i].size / 1024, + ctime(&(temp_list[i].mtime))); + *dump_list = temp_list; +exit: + for (i = 0; i < scan_num; i++) + free(scan_list[i]); + free(scan_list); + close(fd); + + return dump_num; +} + +static int check_disk_available(const char *path, int check_size) +{ + struct statfs lstatfs; + int avail_size = 0; + + if (!path) + return -1; + + if (statfs(path, &lstatfs) < 0) + return -1; + avail_size = (int)(lstatfs.f_bavail * (lstatfs.f_bsize / 1024)); + + if (check_size > avail_size) { + LOGI("avail_size is (%d)", avail_size); + return -1; + } + + return 0; +} + +static int remove_file(struct file_info file) +{ + if (file.isdir) + return remove_dir(file.path, 1); + else + return unlink(file.path); +} + +static void clean_dump(void) +{ + struct file_info *dump_list = NULL; + int i, scan_num, dump_num; + int next = 0; + size_t usage = 0; + time_t cur_time; + + dump_lock(); + + scan_num = scan_dump(&dump_list); + if (scan_num <= 0) { + dump_unlock(); + return; + } + dump_num = scan_num; + + /* Retention time check */ + cur_time = time(NULL); + for (i = 0; i < scan_num; i++) { + usage += dump_list[i].size; + if (max_retention_sec && + dump_list[i].mtime > 0 && + dump_list[i].mtime + max_retention_sec < cur_time) { + if (remove_file(dump_list[i]) < 0) { + LOGE("Failed to remove %s", dump_list[i].path); + continue; + } + LOGI("Reached the maximum retention time %d, so remove (%s)", + max_retention_sec, dump_list[i].path); + dump_num--; + next = i + 1; + usage -= dump_list[i].size; + } + } + + /* Check the number of dumps */ + if (max_crash_dump && + 0 < dump_num && max_crash_dump < dump_num) { + for (i = next; i < scan_num; i++) { + if (remove_file(dump_list[i]) < 0) { + LOGE("Failed to remove %s", dump_list[i].path); + continue; + } + LOGI("Reached the maximum number of dump %d/%d, so remove (%s)", + dump_num, max_crash_dump, + dump_list[i].path); + dump_num--; + next = i + 1; + usage -= dump_list[i].size; + if (dump_num <= 0 || dump_num <= max_crash_dump) + break; + } + } + + /* Check the max system use size */ + if (system_max_use && + 0 < dump_num && system_max_use < usage / 1024) { + for (i = next; i < scan_num; i++) { + if (remove_file(dump_list[i]) < 0) { + LOGE("Failed to remove %s", dump_list[i].path); + dump_num--; + continue; + } + LOGI("Reached the maximum disk usage %d/%d kb, so remove (%s)", + usage / 1024, system_max_use, + dump_list[i].path); + dump_num--; + usage -= dump_list[i].size; + if (dump_num <= 0 || usage / 1024 <= system_max_use) + break; + } + } + + /* Check disk free space to keep */ + if (system_keep_free && + check_disk_available(CRASH_CHECK_DISK_PATH, + system_keep_free) < 0) { + LOGI("Disk is not available! so set the maximum number of dump to 1"); + max_crash_dump = 1; + } + + for (i = 0; i < dump_num; i++) + free(dump_list[i].path); + free(dump_list); + + dump_unlock(); +} + int main(int argc, char *argv[]) { prctl(PR_SET_DUMPABLE, 0); + /* Get Configuration */ + get_config(); + /* Create crash directories */ if (make_dump_dir() < 0) exit(EXIT_FAILURE); @@ -406,7 +787,13 @@ int main(int argc, char *argv[]) execute_crash_modules(argc, argv, DEBUG); /* Tar compression */ - compress(); + if (allow_zip) + compress(); + else + move_dump_dir(); + + /* Check configured limits */ + clean_dump(); return 0; } diff --git a/src/crash-manager/crash-manager.conf b/src/crash-manager/crash-manager.conf new file mode 100644 index 0000000..3489165 --- /dev/null +++ b/src/crash-manager/crash-manager.conf @@ -0,0 +1,6 @@ +[CrashManager] +SystemMaxUse=10240 +SystemKeepFree=0 +MaxRetentionSec=1296000 +MaxCrashDump=1 +AllowZip=yes diff --git a/src/shared/util.c b/src/shared/util.c index 6d3cf2a..01445fd 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -438,6 +438,7 @@ int get_directory_usage(char *path) struct stat st; size_t usage = 0; int fd = -1; + int ret; fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); if (fd < 0) @@ -448,10 +449,7 @@ int get_directory_usage(char *path) return -1; } - if ((readdir_r(dir, &e, &de)) != 0) - de = NULL; - - while (de) { + while ((ret = readdir_r(dir, &e, &de)) == 0 && de) { if (!strncmp(de->d_name, ".", 2) || !strncmp(de->d_name, "..", 3)) continue; if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { -- 2.7.4 From 54f89ccc1e18c6349344d4075d2b83e323a576f4 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Mon, 28 Nov 2016 17:57:57 +0900 Subject: [PATCH 16/16] Change compressing format to zip Change compressing format from tar.gz to zip due to compatibility issues Change-Id: I1e08c1c139617af9baf3b488c3b8db4bd360e95c Signed-off-by: Sunmin Lee --- packaging/crash-worker.spec | 1 + src/crash-manager/crash-manager.c | 19 +++++++++---------- src/log_dump/log_dump.c | 11 ++++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 7e11142..e61b431 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -26,6 +26,7 @@ Requires(post): coreutils Requires(post): tar Requires(post): gzip Requires: libunwind +Requires: zip # If you need support for core dump files (see building below), # you should add this dependency # Requires: libebl diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index d0142df..80d5422 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -243,7 +243,7 @@ static int set_crash_info(char *argv[]) if (allow_zip) ret = snprintf(crash_info.result_path, sizeof(crash_info.result_path), - "%s/%s.tar.gz", CRASH_PATH, crash_info.name); + "%s/%s.zip", CRASH_PATH, crash_info.name); else ret = snprintf(crash_info.result_path, sizeof(crash_info.result_path), @@ -494,29 +494,28 @@ static void dump_unlock(void) static void compress(void) { int ret; - char tar_path[PATH_MAX]; + char zip_path[PATH_MAX]; char command[PATH_MAX]; - ret = snprintf(tar_path, sizeof(tar_path), "%s/report.tar.gz", + ret = snprintf(zip_path, sizeof(zip_path), "%s/report.zip", crash_info.temp_dir); if (ret < 0) { - LOGE("Failed to snprintf for tar path"); + LOGE("Failed to snprintf for zip path"); return; } - ret = snprintf(command, sizeof(command), - "/bin/tar -czf %s -C %s %s", - tar_path, crash_info.temp_dir, crash_info.name); + ret = snprintf(command, sizeof(command), "cd %s && /bin/zip -r %s %s > /dev/null 2>&1", + crash_info.temp_dir, zip_path, crash_info.name); if (ret < 0) { - LOGE("Failed to snprintf for tar command"); + LOGE("Failed to snprintf for zip command"); return; } system_command(command); dump_lock(); - if (rename(tar_path, crash_info.result_path) < 0) + if (rename(zip_path, crash_info.result_path) < 0) LOGE("Failed to move %s to %s", - tar_path, crash_info.result_path); + zip_path, crash_info.result_path); dump_unlock(); ret = remove_dir(crash_info.temp_dir, 1); diff --git a/src/log_dump/log_dump.c b/src/log_dump/log_dump.c index 912aeef..ffe3c56 100644 --- a/src/log_dump/log_dump.c +++ b/src/log_dump/log_dump.c @@ -176,19 +176,20 @@ int log_dump(int option) } ret = snprintf(command, sizeof(command), - "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s %s", + "cd %s && /bin/zip -r %s/%s%s.zip %s %s > /dev/null 2>&1", + LOG_DUMP_ROOT, LOG_DUMP_RESULT, dump_filename, timestr, - LOG_DUMP_ROOT, basename(dump_dirname), - basename(crash_dirname)); + basename(dump_dirname), basename(crash_dirname)); if (ret < 0) { LOGE("Failed to snprintf for command"); goto exit; } } else { ret = snprintf(command, sizeof(command), - "/bin/tar -zcf %s/%s%s.tar.gz -C %s %s", + "cd %s && /bin/zip -r %s/%s%s.zip %s > /dev/null 2>&1", + LOG_DUMP_ROOT, LOG_DUMP_RESULT, dump_filename, timestr, - LOG_DUMP_ROOT, basename(dump_dirname)); + basename(dump_dirname)); if (ret < 0) { LOGE("Failed to snprintf for command"); goto exit; -- 2.7.4