From aa2021fef99fb09e9b1080f613ad9b9d1e790d78 Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Tue, 20 Aug 2019 13:39:42 +0200 Subject: [PATCH 01/16] Move code to the shared library Change-Id: I05f3bc5902bd7b13b4f50dac32622e7f3cbaedab --- packaging/crash-worker.spec | 15 ++- src/crash-manager/CMakeLists.txt | 21 +++- src/crash-manager/crash-manager.c | 198 ++++------------------------------ src/crash-manager/crash-manager.h | 62 +++++++++++ src/crash-manager/crash-manager.pc.in | 10 ++ src/crash-manager/main.c | 149 +++++++++++++++++++++++++ 6 files changed, 272 insertions(+), 183 deletions(-) create mode 100644 src/crash-manager/crash-manager.h create mode 100644 src/crash-manager/crash-manager.pc.in create mode 100644 src/crash-manager/main.c diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 2f38a78..a597a4b 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -54,6 +54,11 @@ Requires: %{_bindir}/buxton2ctl %description crash-manager +%package devel +Summary: Crash-manager development package +%description devel +This package provides library and header files. + %if %{with doc} %package doc Summary: Documentation package for crash-worker @@ -136,7 +141,8 @@ export CFLAGS+=" -Werror" -DLOG_DUMP=%{on_off logdump} \ -DLIVEDUMPER=%{on_off livedumper} \ -DUPGRADE_SCRIPT_PATH=%{upgrade_script_path} \ - -DLOGGER=dlog + -DLOGGER=dlog \ + -DVERSION=%{version} make %{?jobs:-j%jobs} %if %{with doc} @@ -207,6 +213,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %{_libexecdir}/crash-stack %{_libexecdir}/crash-popup-launch %{_libexecdir}/crash-notify-send +%{_libdir}/libcrash-manager.so.* %if %{with logdump} %dir %{crash_all_log} @@ -225,6 +232,11 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload #upgrade script %attr(-,root,root) %{upgrade_script_path}/500.crash-manager-upgrade.sh +%files devel +%{_includedir}/crash-manager.h +%{_libdir}/libcrash-manager.so +%{_datadir}/pkgconfig/*.pc + %if %{with doc} %files doc %{_datadir}/doc/crash-worker @@ -251,3 +263,4 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %manifest %{name}.manifest %{_bindir}/livedumper %endif + diff --git a/src/crash-manager/CMakeLists.txt b/src/crash-manager/CMakeLists.txt index ce803d8..b935621 100644 --- a/src/crash-manager/CMakeLists.txt +++ b/src/crash-manager/CMakeLists.txt @@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(crash-manager C) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) -SET(CRASH_MANAGER_SRCS +SET(LIB_CRASH_MANAGER_SRCS crash-manager.c so-info.c ${CMAKE_SOURCE_DIR}/src/shared/util.c @@ -10,6 +10,10 @@ SET(CRASH_MANAGER_SRCS ${CMAKE_SOURCE_DIR}/src/shared/config.c ) +SET(CRASH_MANAGER_SRCS + main.c + ) + INCLUDE(FindPkgConfig) pkg_check_modules(crash-manager_pkgs REQUIRED dlog @@ -30,8 +34,14 @@ ENDFOREACH(flag) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") +ADD_LIBRARY(libcrash-manager SHARED ${LIB_CRASH_MANAGER_SRCS}) +SET_TARGET_PROPERTIES(libcrash-manager PROPERTIES SOVERSION 1) +SET_TARGET_PROPERTIES(libcrash-manager PROPERTIES PUBLIC_HEADER crash-manager.h) +SET_TARGET_PROPERTIES(libcrash-manager PROPERTIES OUTPUT_NAME crash-manager) +TARGET_LINK_LIBRARIES(libcrash-manager ${crash-manager_pkgs_LDFLAGS}) + ADD_EXECUTABLE(${PROJECT_NAME} ${CRASH_MANAGER_SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie -lrt) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie -lrt libcrash-manager) set(CRASH_POPUP crash-popup-launch) ADD_EXECUTABLE(${CRASH_POPUP} ${CRASH_POPUP}.c) @@ -43,17 +53,24 @@ ADD_EXECUTABLE(${CRASH_NOTIFY} dbus_notify.c) TARGET_LINK_LIBRARIES(${CRASH_NOTIFY} ${helper_pkgs_LDFLAGS} -pie) install(TARGETS ${CRASH_NOTIFY} DESTINATION libexec) +INSTALL(TARGETS libcrash-manager LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include) + INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) CONFIGURE_FILE(500.${PROJECT_NAME}-upgrade.sh.in 500.${PROJECT_NAME}-upgrade.sh @ONLY) CONFIGURE_FILE(70-${PROJECT_NAME}.conf.in 70-${PROJECT_NAME}.conf @ONLY) +CONFIGURE_FILE(crash-manager.pc.in crash-manager.pc @ONLY) INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.conf DESTINATION /etc PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.pc + DESTINATION share/pkgconfig + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) + INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/70-${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 7d30c92..be79b5b 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -51,11 +51,10 @@ #include "shared/spawn.h" #include "shared/util.h" #include "so-info.h" +#include "crash-manager.h" /* Parsing */ #define KEY_MAX 255 -#define APPID_MAX 128 -#define PKGNAME_MAX 128 #define CRASH_TEMP_SUBDIR "/temp/" #define CRASH_PATH_SUBDIR "/dump/" @@ -86,36 +85,6 @@ config_t config; static char* crash_dump_path; static char* crash_temp_path; -/* Paths and variables */ -struct crash_info { - pid_t pid_info; - pid_t tid_info; - int uid_info; - int gid_info; - int sig_info; - char *cmd_line; - char *cmd_path; - time_t time_info; - char *temp_dir; - char *name; - char *result_path; - char *pfx; - char *info_path; - char *core_path; - char *log_path; - char appid[APPID_MAX]; - char pkgid[PKGNAME_MAX]; - char *output_path; - bool livedump; - bool kill; - bool print_result_path; -#ifdef SYS_ASSERT - char *sysassert_cs_path; - bool have_sysassert_report; -#endif - int prstatus_fd; -}; - /* pkgmgrinfo filter list function for getting application ID */ static int appinfo_get_appid_func(pkgmgrinfo_appinfo_h handle, void *user_data) @@ -339,125 +308,7 @@ close_fd: return -1; } -static void print_help(const char *name) -{ - printf("Syntax: %s [OPTIONS]\n" - "\n" - " -p --pid=PID PID of dumped process\n" - " -u --uid=UID real UID of dumped process\n" - " -g --gid=GID real GID of dumped process\n" - " -i --tid=TID TID of thread that triggered core dump\n" - " -s --signal=SIG number of signal causing dump\n" - " -t --time=TIME time of dump, expressed as seconds since the Epoch\n" - " -l --live get coredump of running process\n" - " -k --kill-after-dump kill after dump (only with --live option)\n" - " -r --print print report path to stdout\n" - " -o --output output directory\n" - " -h --help this message\n" - "\n" - "for --live option only --pid is required\n" - "\n", name); -} - -static bool parse_args(struct crash_info *cinfo, int argc, char *argv[]) -{ -#define QUOTE(member) #member -#define GET_NUMBER(member) \ - errno = 0; \ - cinfo->member##_info = strtol(optarg, NULL, 10); \ - if (errno != 0) { \ - _D("%s argument error\n", QUOTE(member)); \ - printf("%s argument error\n", QUOTE(member)); \ - return false; \ - } - - bool result = true; - int opt; - bool pid_set = false; - bool uid_set = false; - bool gid_set = false; - bool sig_set = false; - - struct option long_options[] = { - {"pid", required_argument, NULL, 'p'}, - {"uid", required_argument, NULL, 'u'}, - {"gid", required_argument, NULL, 'g'}, - {"tid", required_argument, NULL, 'i'}, - {"signal", required_argument, NULL, 's'}, - {"time", required_argument, NULL, 't'}, - {"live", no_argument, NULL, 'l'}, - {"kill-after-dump", no_argument, NULL, 'k'}, - {"print", no_argument, NULL, 'r'}, - {"output", required_argument, NULL, 'o'}, - {"help", no_argument, NULL, 'h'}, - }; - - while ((opt = getopt_long(argc, argv, "p:u:g:i:s:t:hlkro:", long_options, NULL)) != -1) { - switch (opt) { - case 'p': - GET_NUMBER(pid) - pid_set = true; - break; - case 'u': - GET_NUMBER(uid) - uid_set = true; - break; - case 'g': - GET_NUMBER(gid) - gid_set = true; - break; - case 'i': - GET_NUMBER(tid) - break; - case 's': - GET_NUMBER(sig) - sig_set = true; - break; - case 't': - GET_NUMBER(time) - break; - case 'l': - cinfo->livedump = true; - break; - case 'k': - cinfo->kill = true; - break; - case 'r': - cinfo->print_result_path = true; - break; - case 'o': - cinfo->output_path = optarg; - _D("output path: %s\n", optarg); - break; - case 'h': - default: - print_help(argv[0]); - return false; - } - } - - if (!pid_set || (!cinfo->livedump && (!gid_set || !uid_set || !sig_set))) { - printf("Not enough parameters.\n\n"); - print_help(argv[0]); - return false; - } - - if (cinfo->livedump && sig_set) { - printf("--sig can not be used with --live option\n\n"); - print_help(argv[0]); - return false; - } - - if (!cinfo->livedump && cinfo->kill) { - printf("Option --kill-after-dump can be used only with --live\n"); - return false; - } - return result; -#undef QUOTE -#undef GET_NUMBER -} - -static bool set_crash_info(struct crash_info *cinfo) +bool set_crash_info(struct crash_info *cinfo) { int ret; char *temp_dir_ret = NULL; @@ -1244,7 +1095,7 @@ static void free_crash_info(struct crash_info *cinfo) #endif } -static void crash_info_init(struct crash_info *cinfo) +void crash_info_init(struct crash_info *cinfo) { cinfo->prstatus_fd = -1; cinfo->livedump = false; @@ -1253,6 +1104,13 @@ static void crash_info_init(struct crash_info *cinfo) cinfo->tid_info = -1; cinfo->time_info = 0; cinfo->output_path = NULL; + cinfo->cmd_line = NULL; + cinfo->cmd_path = NULL; + cinfo->temp_dir = NULL; + cinfo->pfx = NULL; + cinfo->result_path = NULL; + cinfo->info_path = NULL; + cinfo->core_path = NULL; } static bool run(struct crash_info *cinfo) @@ -1337,7 +1195,8 @@ static bool run(struct crash_info *cinfo) return true; } -bool crash_manager_prepare(struct crash_info *cinfo) { +static bool crash_manager_prepare(struct crash_info *cinfo) +{ if (!config_init(&config, CRASH_MANAGER_CONFIG_PATH)) return false; @@ -1357,7 +1216,7 @@ bool crash_manager_prepare(struct crash_info *cinfo) { return true; } -static void crash_manager_free(struct crash_info *cinfo) +void crash_manager_free(struct crash_info *cinfo) { if (cinfo->prstatus_fd >= 0) close(cinfo->prstatus_fd); @@ -1368,32 +1227,11 @@ static void crash_manager_free(struct crash_info *cinfo) free_crash_info(cinfo); } -int main(int argc, char *argv[]) +bool crash_manager_direct(struct crash_info *cinfo) { - int res = EXIT_SUCCESS; - struct crash_info cinfo; - - /* - * prctl(PR_SET_DUMPABLE, 0) is not neccessary. Kernel runs the - * crash-manager and sets RLIMIT_CORE to 1 for the process. This is special - * value that prevents from running crash-manager recursively. - */ - - crash_info_init(&cinfo); - - /* Parse args */ - if (!parse_args(&cinfo, argc, argv)) - return EXIT_FAILURE; - - if (!crash_manager_prepare(&cinfo)) { - res = EXIT_FAILURE; - goto exit; - } + if (!crash_manager_prepare(cinfo)) + return false; - if (!run(&cinfo)) - res = EXIT_FAILURE; -exit: - crash_manager_free(&cinfo); - _I("Exiting with exit code %d", res); - return res; + return run(cinfo); } + diff --git a/src/crash-manager/crash-manager.h b/src/crash-manager/crash-manager.h new file mode 100644 index 0000000..244b37a --- /dev/null +++ b/src/crash-manager/crash-manager.h @@ -0,0 +1,62 @@ +/* + * crash-manager + * + * Copyright (c) 2019 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__ + +#include +#include +#include + +#define APPID_MAX 128 +#define PKGNAME_MAX 128 + +/* Paths and variables */ +struct crash_info { + pid_t pid_info; + pid_t tid_info; + int uid_info; + int gid_info; + int sig_info; + char *cmd_line; + char *cmd_path; + time_t time_info; + char *temp_dir; + char *name; + char *result_path; + char *pfx; + char *info_path; + char *core_path; + char *log_path; + char appid[APPID_MAX]; + char pkgid[PKGNAME_MAX]; + char *output_path; + bool livedump; + bool kill; + bool print_result_path; +#ifdef SYS_ASSERT + char *sysassert_cs_path; + bool have_sysassert_report; +#endif + int prstatus_fd; +}; + +bool crash_manager_direct(struct crash_info *cinfo); +void crash_info_init(struct crash_info *cinfo); +void crash_manager_free(struct crash_info *cinfo); +#endif diff --git a/src/crash-manager/crash-manager.pc.in b/src/crash-manager/crash-manager.pc.in new file mode 100644 index 0000000..3f9b266 --- /dev/null +++ b/src/crash-manager/crash-manager.pc.in @@ -0,0 +1,10 @@ +prefix=/usr +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib + +Name: crash-manager +Description: The crash-manager library +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lcrash-manager diff --git a/src/crash-manager/main.c b/src/crash-manager/main.c new file mode 100644 index 0000000..53211e8 --- /dev/null +++ b/src/crash-manager/main.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include "shared/log.h" +#include "crash-manager.h" + +static void print_help(const char *name) +{ + printf("Syntax: %s [OPTIONS]\n" + "\n" + " -p --pid=PID PID of dumped process\n" + " -u --uid=UID real UID of dumped process\n" + " -g --gid=GID real GID of dumped process\n" + " -i --tid=TID TID of thread that triggered core dump\n" + " -s --signal=SIG number of signal causing dump\n" + " -t --time=TIME time of dump, expressed as seconds since the Epoch\n" + " -l --live get coredump of running process\n" + " -k --kill-after-dump kill after dump (only with --live option)\n" + " -r --print print report path to stdout\n" + " -o --output output directory\n" + " -h --help this message\n" + "\n" + "for --live option only --pid is required\n" + "\n", name); +} + +static bool parse_args(struct crash_info *cinfo, int argc, char *argv[]) +{ +#define QUOTE(member) #member +#define GET_NUMBER(member) \ + do {\ + errno = 0; \ + cinfo->member##_info = strtol(optarg, NULL, 10); \ + if (errno != 0) { \ + _D("%s argument error\n", QUOTE(member)); \ + printf("%s argument error\n", QUOTE(member)); \ + return false; \ + } \ + } while(0) + + bool result = true; + int opt; + bool pid_set = false; + bool uid_set = false; + bool gid_set = false; + bool sig_set = false; + + struct option long_options[] = { + {"pid", required_argument, NULL, 'p'}, + {"uid", required_argument, NULL, 'u'}, + {"gid", required_argument, NULL, 'g'}, + {"tid", required_argument, NULL, 'i'}, + {"signal", required_argument, NULL, 's'}, + {"time", required_argument, NULL, 't'}, + {"live", no_argument, NULL, 'l'}, + {"kill-after-dump", no_argument, NULL, 'k'}, + {"print", no_argument, NULL, 'r'}, + {"output", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, + }; + + while ((opt = getopt_long(argc, argv, "p:u:g:i:s:t:hlkro:", long_options, NULL)) != -1) { + switch (opt) { + case 'p': + GET_NUMBER(pid); + pid_set = true; + break; + case 'u': + GET_NUMBER(uid); + uid_set = true; + break; + case 'g': + GET_NUMBER(gid); + gid_set = true; + break; + case 'i': + GET_NUMBER(tid); + break; + case 's': + GET_NUMBER(sig); + sig_set = true; + break; + case 't': + GET_NUMBER(time); + break; + case 'l': + cinfo->livedump = true; + break; + case 'k': + cinfo->kill = true; + break; + case 'r': + cinfo->print_result_path = true; + break; + case 'o': + cinfo->output_path = optarg; + _D("output path: %s\n", optarg); + break; + case 'h': + default: + print_help(argv[0]); + return false; + } + } + + if (!pid_set || (!cinfo->livedump && (!gid_set || !uid_set || !sig_set))) { + printf("Not enough parameters.\n\n"); + print_help(argv[0]); + return false; + } + + if (cinfo->livedump && sig_set) { + printf("--sig can not be used with --live option\n\n"); + print_help(argv[0]); + return false; + } + + if (!cinfo->livedump && cinfo->kill) { + printf("Option --kill-after-dump can be used only with --live\n"); + return false; + } + return result; +#undef QUOTE +#undef GET_NUMBER +} + + +int main(int argc, char *argv[]) +{ + struct crash_info cinfo; + + /* + * prctl(PR_SET_DUMPABLE, 0) is not neccessary. Kernel runs the + * crash-manager and sets RLIMIT_CORE to 1 for the process. This is special + * value that prevents from running crash-manager recursively. + */ + + crash_info_init(&cinfo); + + /* Parse args */ + if (!parse_args(&cinfo, argc, argv)) + return EXIT_FAILURE; + + int res = crash_manager_direct(&cinfo) ? EXIT_SUCCESS : EXIT_FAILURE; + + crash_manager_free(&cinfo); + _I("Exiting with exit code %d", res); + return res; +} -- 2.7.4 From 0d395b1e977387028e9515944b9c4e5731f52f19 Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Thu, 25 Jul 2019 11:02:43 +0200 Subject: [PATCH 02/16] Add crash manager API Privileged processes can send a D-Bus method call to create report of any living process. Signature is (iss): - INT (in) PID - STRING (in) dump reason - STRING (out) report path There is a library libcrashservice that sends the D-Bus method call. A function signature is: int livedump_pid(pid_t pid, const char *dump_reason, char *report_path); Change-Id: Id8528bdbaac517d4b5fc649821368e0ff020862f --- CMakeLists.txt | 7 + packaging/crash-worker.spec | 20 +- packaging/crash-worker_system-tests.spec | 5 + src/crash-manager/crash-manager.c | 38 +++ src/crash-manager/crash-manager.h | 1 + src/crash-service/CMakeLists.txt | 60 ++++ src/crash-service/crash-service.c | 335 +++++++++++++++++++++ src/crash-service/crash-service.conf | 14 + src/crash-service/crash-service.pc.in | 10 + src/crash-service/crash-service.service.m4 | 10 + src/crash-service/libcrash-service.c | 94 ++++++ src/crash-service/libcrash-service.h | 30 ++ .../org.tizen.system.crash.livedump.service | 4 + src/shared/util.c | 30 ++ src/shared/util.h | 2 + tests/system/CMakeLists.txt | 1 + .../libcrash-service/libcrash-service.sh.template | 47 +++ tests/system/utils/CMakeLists.txt | 11 + tests/system/utils/libcrash-servicetest.c | 47 +++ 19 files changed, 764 insertions(+), 2 deletions(-) create mode 100644 src/crash-service/CMakeLists.txt create mode 100644 src/crash-service/crash-service.c create mode 100644 src/crash-service/crash-service.conf create mode 100644 src/crash-service/crash-service.pc.in create mode 100644 src/crash-service/crash-service.service.m4 create mode 100644 src/crash-service/libcrash-service.c create mode 100644 src/crash-service/libcrash-service.h create mode 100644 src/crash-service/org.tizen.system.crash.livedump.service create mode 100755 tests/system/libcrash-service/libcrash-service.sh.template create mode 100644 tests/system/utils/libcrash-servicetest.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0053f4c..df5c180 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,5 +26,12 @@ IF("${LIVEDUMPER}" STREQUAL "ON") ADD_SUBDIRECTORY(src/livedumper) ENDIF() +IF("${CRASH_SERVICE}" STREQUAL "ON") + if (NOT "${LIVEDUMPER}" STREQUAL "ON") + message(FATAL_ERROR "Livedumper is required to build crash-service") + ENDIF() + ADD_SUBDIRECTORY(src/crash-service) +ENDIF() + ADD_SUBDIRECTORY(tests) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index a597a4b..015bb07 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -4,11 +4,13 @@ %define _with_tests on %define _with_logdump on %define _with_livedumper on +%define _with_crashservice on %bcond_with doc %bcond_with sys_assert %bcond_with tests %bcond_with logdump %bcond_with livedumper +%bcond_with crashservice # NOTE: To disable coredump set DumpCore=0 in configuration file @@ -55,6 +57,7 @@ Requires: %{_bindir}/buxton2ctl crash-manager %package devel +Requires: crash-worker Summary: Crash-manager development package %description devel This package provides library and header files. @@ -140,6 +143,7 @@ export CFLAGS+=" -Werror" -DSYS_ASSERT=%{on_off sys_assert} \ -DLOG_DUMP=%{on_off logdump} \ -DLIVEDUMPER=%{on_off livedumper} \ + -DCRASH_SERVICE=%{on_off crashservice} \ -DUPGRADE_SCRIPT_PATH=%{upgrade_script_path} \ -DLOGGER=dlog \ -DVERSION=%{version} @@ -215,6 +219,14 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %{_libexecdir}/crash-notify-send %{_libdir}/libcrash-manager.so.* +%if %{with crashservice} +%attr(0750,system_fw,system_fw) %{_bindir}/crash-service +%attr(-,root,root) %{_unitdir}/crash-service.service +%attr(-,root,root) %{_sysconfdir}/dbus-1/system.d/crash-service.conf +%attr(-,root,root) %{_datadir}/dbus-1/system-services/org.tizen.system.crash.livedump.service +%{_libdir}/libcrash-service.so.* +%endif + %if %{with logdump} %dir %{crash_all_log} %{crash_dump_gen}/* @@ -235,7 +247,12 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %files devel %{_includedir}/crash-manager.h %{_libdir}/libcrash-manager.so -%{_datadir}/pkgconfig/*.pc +%{_datadir}/pkgconfig/crash-manager.pc +%if %{with crashservice} +%{_includedir}/libcrash-service.h +%{_libdir}/libcrash-service.so +%{_datadir}/pkgconfig/crash-service.pc +%endif %if %{with doc} %files doc @@ -263,4 +280,3 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %manifest %{name}.manifest %{_bindir}/livedumper %endif - diff --git a/packaging/crash-worker_system-tests.spec b/packaging/crash-worker_system-tests.spec index 3fea883..320c900 100644 --- a/packaging/crash-worker_system-tests.spec +++ b/packaging/crash-worker_system-tests.spec @@ -16,6 +16,9 @@ Source0: %{name}-%{version}.tar.gz Source1001: crash-worker_system-tests.manifest BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(rpm) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(crash-service) BuildRequires: cmake Requires: diff @@ -75,10 +78,12 @@ cd tests/system %{_libdir}/crash-worker_system-tests/time_test/time_test.sh %{_libdir}/crash-worker_system-tests/utils/btee %{_libdir}/crash-worker_system-tests/utils/kenny +%{_libdir}/crash-worker_system-tests/utils/libcrash-servicetest %{_libdir}/crash-worker_system-tests/utils/minicore-utils.sh %{_libdir}/crash-worker_system-tests/wait_for_opt_usr/wait_for_opt_usr.sh %{_libdir}/crash-worker_system-tests/without_core/without_core.sh %{_libdir}/crash-worker_system-tests/output_param/output_param.sh +%{_libdir}/crash-worker_system-tests/libcrash-service/libcrash-service.sh %if %{with livedumper} %{_libdir}/crash-worker_system-tests/livedumper/livedumper.sh %endif diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index be79b5b..dd2bab1 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -1216,6 +1216,18 @@ static bool crash_manager_prepare(struct crash_info *cinfo) return true; } +static void write_dump_reason(const char *reason, const char *base_dir, const char *name) +{ + char *reason_name; + + if (asprintf(&reason_name, "%s.dump_reason", name) == -1) { + _E("Failed to asprintf for reason_name: %m"); + } else { + write_to_file(reason, base_dir, reason_name); + free(reason_name); + } +} + void crash_manager_free(struct crash_info *cinfo) { if (cinfo->prstatus_fd >= 0) @@ -1235,3 +1247,29 @@ bool crash_manager_direct(struct crash_info *cinfo) return run(cinfo); } +bool crash_manager_livedump_pid(pid_t pid, const char *dump_reason, char *report_path, size_t report_path_len) +{ + bool result = false; + struct crash_info cinfo; + crash_info_init(&cinfo); + + cinfo.livedump = true; + cinfo.pid_info = pid; + + if (!crash_manager_prepare(&cinfo)) + goto exit; + + write_dump_reason(dump_reason, cinfo.pfx, cinfo.name); + + if (!run(&cinfo)) + goto exit; + + strncpy(report_path, cinfo.result_path, report_path_len); + + result = true; +exit: + crash_manager_free(&cinfo); + _I("Exiting with %s", result ? "success" : "fail"); + return result; +} + diff --git a/src/crash-manager/crash-manager.h b/src/crash-manager/crash-manager.h index 244b37a..7c102bc 100644 --- a/src/crash-manager/crash-manager.h +++ b/src/crash-manager/crash-manager.h @@ -57,6 +57,7 @@ struct crash_info { }; bool crash_manager_direct(struct crash_info *cinfo); +bool crash_manager_livedump_pid(pid_t pid, const char *dump_reason, char *report_path, size_t report_path_len); void crash_info_init(struct crash_info *cinfo); void crash_manager_free(struct crash_info *cinfo); #endif diff --git a/src/crash-service/CMakeLists.txt b/src/crash-service/CMakeLists.txt new file mode 100644 index 0000000..37ad6b1 --- /dev/null +++ b/src/crash-service/CMakeLists.txt @@ -0,0 +1,60 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(crash-service C) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) + +SET(CRASH_SERVICE_SRCS + crash-service.c + ) + +INCLUDE(FindPkgConfig) + +pkg_check_modules(crash-service_pkgs REQUIRED + dlog + gio-2.0 + ) + +FOREACH(flag ${crash-service_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE -Wno-unused-function -Wno-unused-const-variable") + +INCLUDE(${CMAKE_SOURCE_DIR}/cmake/ProcessM4.cmake) + +LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/crash-manager) +ADD_EXECUTABLE(${PROJECT_NAME} ${CRASH_SERVICE_SRCS}) +ADD_DEPENDENCIES(${PROJECT_NAME} crash-manager) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-service_pkgs_LDFLAGS} -pie -lrt -lcrash-manager) + +ADD_LIBRARY(libcrash-service SHARED libcrash-service.c) +SET_TARGET_PROPERTIES(libcrash-service PROPERTIES + SOVERSION 1 + PUBLIC_HEADER libcrash-service.h + OUTPUT_NAME crash-service) + +PROCESS_M4("${M4_DEFINES}" + "${CMAKE_CURRENT_SOURCE_DIR}/crash-service.service.m4" + "${CMAKE_CURRENT_SOURCE_DIR}/crash-service.service") + +CONFIGURE_FILE(crash-service.pc.in crash-service.pc @ONLY) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.system.crash.livedump.service + DESTINATION /usr/share/dbus-1/system-services) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/crash-service.conf + DESTINATION /etc/dbus-1/system.d) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/crash-service.service + DESTINATION /usr/lib/systemd/system + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + +INSTALL(TARGETS libcrash-service LIBRARY DESTINATION /usr/lib/ + PUBLIC_HEADER DESTINATION /usr/include) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/crash-service.pc + DESTINATION share/pkgconfig) diff --git a/src/crash-service/crash-service.c b/src/crash-service/crash-service.c new file mode 100644 index 0000000..fa223f2 --- /dev/null +++ b/src/crash-service/crash-service.c @@ -0,0 +1,335 @@ +/* + * crash-service + * + * Copyright (c) 2019 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 "crash-manager/crash-manager.h" +#include "libcrash-service.h" +#include "shared/log.h" + +/* Dbus activation */ +#define CRASH_BUS_NAME "org.tizen.system.crash.livedump" +#define CRASH_OBJECT_PATH "/Org/Tizen/System/Crash/Livedump" + +#define TIMEOUT_INTERVAL_SEC 60 +#define TIMEOUT_LIVEDUMP_SEC 50 + +#define CS_ERROR 1 +#define CS_ERR_PARAM 1 +#define CS_ERR_TIMEOUT 2 +#define CS_ERR_READ 3 +#define CS_ERR_INTERNAL 4 + +static GMainLoop *loop; +static GMutex timeout_mutex; +static guint timeout_id; +static GDBusNodeInfo *introspection_data; +static const gchar introspection_xml[] = +"" +" " +" " +" " +" " +" " +" " +" " +""; + +void child_exit(int sig) +{ + wait(NULL); +} + +static int timeout_cb(gpointer data) +{ + _I("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_SEC, timeout_cb, loop); + + g_mutex_unlock(&timeout_mutex); + _D("Add loop timeout (%d)", TIMEOUT_INTERVAL_SEC); +} + +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); + _D("Remove loop timeout"); +} + +struct livedump_cb_data { + int read_fd; + GDBusMethodInvocation *invocation; + GSource* source; + pid_t child_pid; +}; + +static bool data_ready(int fd) +{ + fd_set rfd; + FD_ZERO(&rfd); + FD_SET(fd, &rfd); + struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; + int retval = select(fd+1, &rfd, NULL, NULL, &tv); + if (retval == -1) + _E("select() error: %m"); + return retval == 1; +} + +static gboolean read_result_cb(gpointer data) +{ + struct livedump_cb_data *cb_data = (struct livedump_cb_data*)data; + char report_path[PATH_MAX]; + + if (!data_ready(cb_data->read_fd)) { + _I("Report is not ready after %d seconds.", TIMEOUT_LIVEDUMP_SEC); + g_dbus_method_invocation_return_error(cb_data->invocation, + CS_ERROR, + CS_ERR_TIMEOUT, + "Report is not ready"); + kill(cb_data->child_pid, SIGKILL); + goto end; + } else { + if (read(cb_data->read_fd, report_path, sizeof(report_path)) == -1) { + _E("Read from child error: %m"); + g_dbus_method_invocation_return_error(cb_data->invocation, + CS_ERROR, + CS_ERR_READ, + "Error while obtaining report path"); + goto end; + } + } + + g_dbus_method_invocation_return_value(cb_data->invocation, + g_variant_new("(s)", report_path)); +end: + close(cb_data->read_fd); + free(cb_data); + return G_SOURCE_REMOVE; +} + +static bool livedump_run(int write_fd, pid_t pid, const gchar *dump_reason) +{ + char report_path[PATH_MAX]; + + if (!crash_manager_livedump_pid(pid, dump_reason, report_path, sizeof(report_path))) { + _E("crash_manager_livedump_pid error"); + return false; + } + + if (write(write_fd, report_path, strlen(report_path) + 1) == -1) { + _E("Write report_path error: %m"); + close(write_fd); + return false; + } + + close(write_fd); + return true; +} + +static void livedump_pid_handler(GDBusMethodInvocation *invocation, pid_t pid, gchar *dump_reason) +{ + /* + * We want to run the livedump in different process so as not to + * block the main loop, to be able to handle many method calls + * in the same time, so we need a communication cannel to send + * back a result report path. + */ + int fds[2]; + if (pipe(fds) == -1) { + _E("Pipe error: %m"); + g_dbus_method_invocation_return_error(invocation, + CS_ERROR, + CS_ERR_INTERNAL, + "Internal error"); + return; + } + + struct livedump_cb_data *cb_data = (struct livedump_cb_data*)malloc(sizeof(struct livedump_cb_data)); + if (cb_data == NULL) { + _E("cb_data malloc() error: %m"); + exit(EXIT_FAILURE); + } + cb_data->read_fd = fds[0]; + cb_data->invocation = invocation; + + GSource *source = g_timeout_source_new_seconds(TIMEOUT_LIVEDUMP_SEC); + cb_data->source = source; + g_source_add_unix_fd(source, fds[0], G_IO_IN); + g_source_set_callback(source, read_result_cb, cb_data, NULL); + g_source_attach(source, NULL); + + pid_t child_pid = fork(); + if (child_pid == 0) { + close(fds[0]); + if (livedump_run(fds[1], pid, dump_reason)) + exit(EXIT_SUCCESS); + else + exit(EXIT_FAILURE); + } else if (child_pid > 0) { + cb_data->child_pid = child_pid; + close(fds[1]); + } else { + _E("fork() error: %m"); + g_dbus_method_invocation_return_error(invocation, + CS_ERROR, + CS_ERR_INTERNAL, + "Internal error"); + close(fds[0]); + close(fds[1]); + } +} + +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) +{ + remove_timeout(); + + if (g_strcmp0(method_name, "livedump_pid") == 0) { + gchar *dump_reason; + const pid_t pid; + + if (g_variant_is_of_type(parameters, G_VARIANT_TYPE("(is)"))) { + g_variant_get(parameters, "(is)", &pid, &dump_reason); + livedump_pid_handler(invocation, pid, dump_reason); + } else { + _E("Parameters are not of the correct type (is)"); + g_dbus_method_invocation_return_error(invocation, + CS_ERROR, + CS_ERR_PARAM, + "Parameters are not of the correct type (is)"); + } + } + + 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; + + GError *error = NULL; + registration_id = g_dbus_connection_register_object(conn, + CRASH_OBJECT_PATH, + introspection_data->interfaces[0], + &interface_vtable, NULL, NULL, &error); + if (registration_id == 0 || error) { + _E("Failed to g_dbus_connection_register_object: %s", error ? error->message : ""); + if (error) + g_error_free(error); + } +} + +static void on_name_acquired(GDBusConnection *conn, + const gchar *name, + gpointer user_data) +{ + _D("Acquired the name %s on the system bus", name); +} + +static void on_name_lost(GDBusConnection *conn, + const gchar *name, + gpointer user_data) +{ + _D("Lost the name %s on the system bus", name); +} + +static bool dbus_init(void) +{ + GError *error = NULL; + + introspection_data = + g_dbus_node_info_new_for_xml(introspection_xml, NULL); + if (introspection_data == NULL) { + _E("Failed to init g_dbus_info_new_for_xml"); + return false; + } + + GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (!conn || error) { + _E("Failed to get dbus: %s", error ? error->message : ""); + if (error) + g_error_free(error); + return false; + } + + 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); + + return true; +} + +int main(void) +{ + signal(SIGCHLD, child_exit); + loop = g_main_loop_new(NULL, false); + + if (!dbus_init()) { + g_main_loop_unref(loop); + return EXIT_FAILURE; + } + + g_mutex_init(&timeout_mutex); + add_timeout(); + + 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 EXIT_SUCCESS; +} diff --git a/src/crash-service/crash-service.conf b/src/crash-service/crash-service.conf new file mode 100644 index 0000000..904d93a --- /dev/null +++ b/src/crash-service/crash-service.conf @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/src/crash-service/crash-service.pc.in b/src/crash-service/crash-service.pc.in new file mode 100644 index 0000000..9d2d7c8 --- /dev/null +++ b/src/crash-service/crash-service.pc.in @@ -0,0 +1,10 @@ +prefix=/usr +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib + +Name: crash-service +Description: The crash-service library +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lcrash-service diff --git a/src/crash-service/crash-service.service.m4 b/src/crash-service/crash-service.service.m4 new file mode 100644 index 0000000..f080f40 --- /dev/null +++ b/src/crash-service/crash-service.service.m4 @@ -0,0 +1,10 @@ +[Unit] +Description=crash service + +[Service] +Type=dbus +BusName=org.tizen.system.crash.livedump +ExecStart=/usr/bin/crash-service +SmackProcessLabel=System +Nice=-5 +KillMode=mixed diff --git a/src/crash-service/libcrash-service.c b/src/crash-service/libcrash-service.c new file mode 100644 index 0000000..25a36bc --- /dev/null +++ b/src/crash-service/libcrash-service.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016-2019 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 + +#define LOG_TAG "LIBCRASH-SERVICE" + +#include "shared/log.h" + +#define BUS_NAME "org.tizen.system.crash.livedump" +#define OBJECT_PATH "/Org/Tizen/System/Crash/Livedump" +#define INTERFACE_NAME "org.tizen.system.crash.livedump" +#define METHOD_NAME "livedump_pid" + +static GDBusConnection* dbus_init(void) +{ + GError *error = NULL; + GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + if (!conn || error) { + _E("Failed to get dbus: %s", error ? error->message : ""); + if (error) + g_error_free(error); + return NULL; + } + + return conn; +} + +bool livedump_pid(pid_t pid, const char *dump_reason, char *report_path, size_t report_path_len) +{ + bool res = true; + GDBusConnection *conn = dbus_init(); + + if (!conn) + return false; + + GVariant *parameters = g_variant_new("(is)", pid, dump_reason); + + GError *error = NULL; + GVariant *reply = g_dbus_connection_call_sync(conn, + BUS_NAME, + OBJECT_PATH, + INTERFACE_NAME, + METHOD_NAME, + parameters, + G_VARIANT_TYPE("(s)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (!reply || error) { + _E("Error while calling livedump_pid via dbus (pid=%d, reason=%s): %s", pid, dump_reason, error ? error->message : ""); + if (error) + g_error_free(error); + res = false; + goto exit; + } + + if (!g_variant_is_of_type(reply, G_VARIANT_TYPE("(s)"))) { + _E("reply is not of the correct type (s)"); + res = false; + goto exit; + } + + gchar *reply_str; + g_variant_get(reply, "(&s)", &reply_str); + if (strlen(reply_str) <= (report_path_len + 1)) { + strncpy(report_path, reply_str, report_path_len); + } else { + _E("Report path (%s) is longer than report_path_len", reply_str); + res = false; + } +exit: + g_object_unref(conn); + return res; +} diff --git a/src/crash-service/libcrash-service.h b/src/crash-service/libcrash-service.h new file mode 100644 index 0000000..a2fa39c --- /dev/null +++ b/src/crash-service/libcrash-service.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 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 LIBCRASH_SERVICE_H +#define LIBCRASH_SERVICE_H +#include +#include + +/** + * @brief Sends a request to the crash-service to create livedump report of specific process. + * @param pid PID of process for which the report should be created. + * @param dump_reason the reason that should be included in the raport. + * @param report_path pointer to the buffer in which will be saved the report path. + * @param report_path_len lenght of buffer for the report path. + * @return true on success and false on error. + */ +extern bool livedump_pid(pid_t pid, const char *dump_reason, char *report_path, size_t report_path_len); +#endif /* LIBCRASH_SERVICE_H */ diff --git a/src/crash-service/org.tizen.system.crash.livedump.service b/src/crash-service/org.tizen.system.crash.livedump.service new file mode 100644 index 0000000..f1fc1fd --- /dev/null +++ b/src/crash-service/org.tizen.system.crash.livedump.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.tizen.system.crash.livedump +Exec=/bin/false +SystemdService=crash-service.service diff --git a/src/shared/util.c b/src/shared/util.c index 1860bab..d5917e7 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -584,6 +584,36 @@ bool file_exists(const char *path) return stat(path, &buf) == 0; } +bool write_to_file(const char *content, const char *base_dir, const char *file_name) +{ + char *path; + bool result = false; + + if (asprintf(&path, "%s/%s", base_dir, file_name) == -1) { + _E("Failed to asprintf for path: %m"); + return false; + } + + int fd = open(path, O_WRONLY | O_CREAT, 0600); + + if (fd < 0) { + _E("Failed to open %s: %m", path); + goto exit; + } + + if (dprintf(fd, "%s", content) < 0) { + _E("Failed to write to file %s: %m", path); + close(fd); + goto exit; + } + + close(fd); + result = true; +exit: + free(path); + return result; +} + /** * @} */ diff --git a/src/shared/util.h b/src/shared/util.h index f3177e8..8e2a82f 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -70,6 +70,8 @@ bool string_ends_with(const char *string, const char *suffix); bool file_exists(const char *path); +bool write_to_file(const char *content, const char *base_dir, const char *file_name); + #ifdef __cplusplus } #endif diff --git a/tests/system/CMakeLists.txt b/tests/system/CMakeLists.txt index 309e572..92796b6 100644 --- a/tests/system/CMakeLists.txt +++ b/tests/system/CMakeLists.txt @@ -40,6 +40,7 @@ configure_test("livedumper") configure_test("extra_script") configure_test("dbus_notify") configure_test("output_param") +configure_test("libcrash-service") get_property(TESTS_LIST GLOBAL PROPERTY TMP_TESTS_LIST) diff --git a/tests/system/libcrash-service/libcrash-service.sh.template b/tests/system/libcrash-service/libcrash-service.sh.template new file mode 100755 index 0000000..611978a --- /dev/null +++ b/tests/system/libcrash-service/libcrash-service.sh.template @@ -0,0 +1,47 @@ +#!/bin/bash + +# Test --output parameter + +if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then + CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@" +fi + +. ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh + +save_core_pattern +trap restore_core_pattern 0 + +echo "|/usr/bin/crash-manager -p %p -u %u -g %g -s %s -t %t" > /proc/sys/kernel/core_pattern + +{ + ${CRASH_WORKER_SYSTEM_TESTS}/utils/kenny 10 & + KENNY_PID=$! + sleep 1 +} 1> /dev/null 2>&1 + +sleep 2 + +rm -rf ${LIVE_DUMP_PATH}/* +REASON="some reason" +${CRASH_WORKER_SYSTEM_TESTS}/utils/libcrash-servicetest -r "${REASON}" ${KENNY_PID} + +wait_for_file ${LIVE_DUMP_PATH}/kenny*zip + +kill -9 ${KENNY_PID} + +trap popd 0 + +pushd ${LIVE_DUMP_PATH} + +unzip kenny*zip +cd kenny* + +if [ ! -f *dump_reason ]; then + fail "dump_reason file doesn't exist" +fi + +if [ "$(cat *dump_reason)" != "${REASON}" ]; then + fail "Dump reason didn't match" +fi + +exit_ok diff --git a/tests/system/utils/CMakeLists.txt b/tests/system/utils/CMakeLists.txt index a486aab..5bd6710 100644 --- a/tests/system/utils/CMakeLists.txt +++ b/tests/system/utils/CMakeLists.txt @@ -8,7 +8,18 @@ find_package(Threads) target_link_libraries(kenny ${CMAKE_THREAD_LIBS_INIT}) set_target_properties(kenny PROPERTIES COMPILE_FLAGS "-std=c++11 -ggdb -O0") +add_executable(libcrash-servicetest libcrash-servicetest.c) + +INCLUDE(FindPkgConfig) +pkg_check_modules(helper_pkgs REQUIRED + crash-service + gio-2.0 + dlog) + +TARGET_LINK_LIBRARIES(libcrash-servicetest crash-service ${helper_pkgs_LDFLAGS}) + install(TARGETS kenny DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils) install(TARGETS btee DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils) install(FILES minicore-utils.sh DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils) +install(TARGETS libcrash-servicetest DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils) diff --git a/tests/system/utils/libcrash-servicetest.c b/tests/system/utils/libcrash-servicetest.c new file mode 100644 index 0000000..c83a2fc --- /dev/null +++ b/tests/system/utils/libcrash-servicetest.c @@ -0,0 +1,47 @@ +#include + +#include +#include +#include +#include + +void help(char *argv_0) +{ + printf("Usage: %s [-r dump_reason] pid\n", argv_0); +} + +int main(int argc, char *argv[]) +{ + int opt; + const char *dump_reason = NULL; + + while ((opt = getopt(argc, argv, "r:")) != -1) { + switch (opt) { + case 'r': + dump_reason = optarg; + break; + default: + help(argv[0]); + exit(EXIT_FAILURE); + } + } + + if (dump_reason == NULL) + dump_reason = "no reason"; + + if (optind >= argc) { + help(argv[0]); + exit(EXIT_FAILURE); + } + pid_t pid = strtol(argv[optind], NULL, 10); + if (pid == 0) { + printf("ERROR: pid must be a number\n"); + help(argv[0]); + return EXIT_FAILURE; + } + + char BUFF[PATH_MAX]; + bool res = livedump_pid(pid, dump_reason, BUFF, PATH_MAX); + printf("res: %s\nreport_path: %s\n", res ? "true" : "false", BUFF); + return res ? EXIT_SUCCESS : EXIT_FAILURE; +} -- 2.7.4 From 13980ada22fd9baec2d7aaab7b46877e660631fb Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 26 Sep 2019 14:29:23 +0200 Subject: [PATCH 03/16] Release 5.5.22 This version brings one major enhancement - livedump API, available for platform service developers. pkgconfig name: crash-service include: libcrash-service.h API: livedump_pid() Change-Id: I25d22fc9f43e647dd48ea4f02cebb2dbb5ac49ec --- packaging/crash-worker.spec | 2 +- packaging/crash-worker_system-tests.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 015bb07..1349392 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -16,7 +16,7 @@ Name: crash-worker Summary: Crash-manager -Version: 5.5.21 +Version: 5.5.22 Release: 1 Group: Framework/system License: Apache-2.0 and BSD diff --git a/packaging/crash-worker_system-tests.spec b/packaging/crash-worker_system-tests.spec index 320c900..2ae412e 100644 --- a/packaging/crash-worker_system-tests.spec +++ b/packaging/crash-worker_system-tests.spec @@ -8,7 +8,7 @@ Name: crash-worker_system-tests Summary: Package with binaries and scripts for crash-worker system tests -Version: 5.5.21 +Version: 5.5.22 Release: 1 Group: Framework/system License: Apache-2.0 and BSD -- 2.7.4 From d546a485ae7eb8c1147aeb79914d59593b993f34 Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Tue, 10 Sep 2019 12:16:38 +0200 Subject: [PATCH 04/16] Run all existing tests from tests/system/ directory This allows to put there tests by other crash-manager related packages Change-Id: I3dea8cdb77cf20c8bed68ff9b8891d87c0bd5da2 --- tests/system/CMakeLists.txt | 6 ------ tests/system/run.sh.template | 13 ++++++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/system/CMakeLists.txt b/tests/system/CMakeLists.txt index 92796b6..767703e 100644 --- a/tests/system/CMakeLists.txt +++ b/tests/system/CMakeLists.txt @@ -2,16 +2,12 @@ cmake_minimum_required(VERSION 2.6) ADD_SUBDIRECTORY(utils) -set_property(GLOBAL PROPERTY TMP_TESTS_LIST "") - macro(CONFIGURE_TEST_FILE dir_name file_name) configure_file("${dir_name}/${file_name}.sh.template" "${dir_name}/${file_name}.sh" @ONLY) INSTALL(DIRECTORY ${dir_name}/ DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/${dir_name} FILES_MATCHING PATTERN "*sh") endmacro() macro(CONFIGURE_TEST test_name) - set_property(GLOBAL APPEND_STRING PROPERTY TMP_TESTS_LIST "\"${test_name}\" ") - set(FILES_LIST ${test_name}) list(APPEND FILES_LIST ${ARGN}) @@ -42,7 +38,5 @@ configure_test("dbus_notify") configure_test("output_param") configure_test("libcrash-service") -get_property(TESTS_LIST GLOBAL PROPERTY TMP_TESTS_LIST) - configure_file("run.sh.template" "run.sh" @ONLY) INSTALL(FILES run.sh DESTINATION ${CRASH_SYSTEM_TESTS_PATH}) diff --git a/tests/system/run.sh.template b/tests/system/run.sh.template index d06754d..6e37c2f 100644 --- a/tests/system/run.sh.template +++ b/tests/system/run.sh.template @@ -1,7 +1,5 @@ #!/bin/bash -TESTS=(@TESTS_LIST@) - if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@" fi @@ -15,7 +13,7 @@ function run_test { GREEN="\033[0;32m" YELLOW="\033[1;33m" NORMAL="\033[0m" - + TEST=${1} echo -ne "${TEST}:\t" echo "===================================" >> ${LOG_FILE} echo "Test ${TEST}:" >> ${LOG_FILE} @@ -40,6 +38,11 @@ function run_test { if [ -f ${LOG_FILE} ]; then rm ${LOG_FILE} fi -for TEST in ${TESTS[@]}; do - run_test ${TEST} + +for DIR in ${CRASH_WORKER_SYSTEM_TESTS}/*/; do + test_name=`basename ${DIR}` + + if [ -x ${CRASH_WORKER_SYSTEM_TESTS}/${test_name}/${test_name}.sh ]; then + run_test ${test_name} + fi done -- 2.7.4 From ca6479c4e2d7623b79984a87f051eab09bf0443c Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Mon, 19 Aug 2019 13:33:15 +0200 Subject: [PATCH 05/16] Separate log_dump from crash-worker crash-worker can be installed without log_dump Change-Id: Ifa045dede15148e4c5215b1a54fd0e3280d75f52 --- CMakeLists.txt | 4 --- packaging/crash-worker.manifest | 1 - packaging/crash-worker.spec | 32 --------------------- packaging/log_dump.manifest | 8 ++++++ packaging/log_dump.spec | 62 +++++++++++++++++++++++++++++++++++++++++ src/log_dump/CMakeLists.txt | 15 ++++++---- 6 files changed, 80 insertions(+), 42 deletions(-) create mode 100644 packaging/log_dump.manifest create mode 100644 packaging/log_dump.spec diff --git a/CMakeLists.txt b/CMakeLists.txt index df5c180..630e1aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,10 +18,6 @@ ENDIF("${SYS_ASSERT}" STREQUAL "ON") ADD_SUBDIRECTORY(src/crash-stack) ADD_SUBDIRECTORY(src/dump_systemstate) -IF("${LOG_DUMP}" STREQUAL "ON") - ADD_SUBDIRECTORY(src/log_dump) -ENDIF() - IF("${LIVEDUMPER}" STREQUAL "ON") ADD_SUBDIRECTORY(src/livedumper) ENDIF() diff --git a/packaging/crash-worker.manifest b/packaging/crash-worker.manifest index c6cdebc..25bee3e 100644 --- a/packaging/crash-worker.manifest +++ b/packaging/crash-worker.manifest @@ -5,6 +5,5 @@ - diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 1349392..bd6cbd7 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -2,13 +2,11 @@ %define on_off() %{expand:%%{?with_%{1}:ON}%%{!?with_%{1}:OFF}} %define _with_tests on -%define _with_logdump on %define _with_livedumper on %define _with_crashservice on %bcond_with doc %bcond_with sys_assert %bcond_with tests -%bcond_with logdump %bcond_with livedumper %bcond_with crashservice @@ -97,10 +95,6 @@ Summary: Livedumper allows to dump core of live process #Debug mode path - existence of file at path below mean that core file should be generated %define debugmode_path %{TZ_SYS_ETC}/.debugmode -#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 @@ -134,14 +128,12 @@ export CFLAGS+=" -Werror" -DMINICOREDUMPER_BIN_PATH=%{_sbindir}/minicoredumper \ -DMINICOREDUMPER_CONFIG_PATH=%{_sysconfdir}/minicoredumper/minicoredumper.cfg.json \ -DLIVEDUMPER_BIN_PATH=%{_bindir}/livedumper \ - -DLOG_DUMP_BIN_PATH=%{_bindir}/log_dump \ -DDUMP_SYSTEMSTATE_BIN_PATH=%{_bindir}/dump_systemstate \ -DCRASH_STACK_BIN_PATH=%{_libexecdir}/crash-stack \ -DCRASH_POPUP_BIN_PATH=%{_libexecdir}/crash-popup-launch \ -DCRASH_NOTIFY_BIN_PATH=%{_libexecdir}/crash-notify-send \ -DCRASH_TESTS_PATH=%{_libdir}/crash-worker-tests \ -DSYS_ASSERT=%{on_off sys_assert} \ - -DLOG_DUMP=%{on_off logdump} \ -DLIVEDUMPER=%{on_off livedumper} \ -DCRASH_SERVICE=%{on_off crashservice} \ -DUPGRADE_SCRIPT_PATH=%{upgrade_script_path} \ @@ -160,14 +152,6 @@ mkdir -p %{buildroot}%{crash_root_path} mkdir -p %{buildroot}%{crash_path} mkdir -p %{buildroot}%{crash_temp} -# log_dump dir -%if %{with logdump} -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}/* -%endif - %post %if %{with sys_assert} if [ ! -d /.build ]; then @@ -186,13 +170,6 @@ fi /usr/bin/chsmack -a "System" -t %{crash_path} /usr/bin/chsmack -a "System" -t %{crash_temp} -%if %{with logdump} -/usr/bin/chsmack -a "System" -t %{crash_dump_gen} -/usr/bin/chsmack -a "System" -t %{crash_dump_gen}/module.d -/usr/bin/chsmack -a "System::Shared" -t %{crash_all_log} -/usr/bin/chsmack -a "_" %{crash_dump_gen}/module.d/* -%endif - %postun %if %{with sys_assert} orig="%{_libdir}/libsys-assert.so" @@ -227,15 +204,6 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %{_libdir}/libcrash-service.so.* %endif -%if %{with logdump} -%dir %{crash_all_log} -%{crash_dump_gen}/* -%attr(-,root,root) %{_unitdir}/log_dump.service -%attr(-,root,root) %{_sysconfdir}/dbus-1/system.d/log_dump.conf -%attr(-,root,root) %{_datadir}/dbus-1/system-services/org.tizen.system.crash.service -%attr(0750,system_fw,system_fw) %{_bindir}/log_dump -%endif - %if %{with sys_assert} %{_libdir}/libsys-assert.so %{_sysconfdir}/tmpfiles.d/sys-assert.conf diff --git a/packaging/log_dump.manifest b/packaging/log_dump.manifest new file mode 100644 index 0000000..a340d2e --- /dev/null +++ b/packaging/log_dump.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packaging/log_dump.spec b/packaging/log_dump.spec new file mode 100644 index 0000000..ce97c0b --- /dev/null +++ b/packaging/log_dump.spec @@ -0,0 +1,62 @@ +Name: log_dump +Summary: log_dump +Version: 5.5.19 +Release: 1 +Group: Framework/system +License: Apache-2.0 and BSD +Source0: %{name}-%{version}.tar.gz +Source1001: log_dump.manifest +Requires: crash-worker +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: cmake +BuildRequires: pkgconfig(pkgmgr-info) + +%description +log_dump + +%prep +%setup -q + +%define crash_root_path %{TZ_SYS_CRASH_ROOT} +%define crash_all_log %{TZ_SYS_ALLLOGS} +%define crash_dump_gen %{TZ_SYS_DUMPGEN} + +%build +cp %{SOURCE1001} . + +%cmake src/log_dump/ \ + -DCRASH_ROOT_PATH=%{crash_root_path} \ + -DDUMP_SYSTEMSTATE_BIN_PATH=%{_bindir}/dump_systemstate \ + -DCRASH_MANAGER_CONFIG_PATH=%{_sysconfdir}/crash-manager.conf + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install +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}/* + +%post +/usr/bin/chsmack -a "System" -t %{crash_dump_gen} +/usr/bin/chsmack -a "System" -t %{crash_dump_gen}/module.d +/usr/bin/chsmack -a "System::Shared" -t %{crash_all_log} +/usr/bin/chsmack -a "_" %{crash_dump_gen}/module.d/* + +%files +%license LICENSE +%manifest log_dump.manifest +%dir %{crash_all_log} +%{crash_dump_gen}/* +%attr(-,root,root) %{_unitdir}/log_dump.service +%attr(-,root,root) %{_sysconfdir}/dbus-1/system.d/log_dump.conf +%attr(-,root,root) %{_datadir}/dbus-1/system-services/org.tizen.system.crash.service +%attr(0750,system_fw,system_fw) %{_bindir}/log_dump + + diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt index a7446a2..cc91ea5 100644 --- a/src/log_dump/CMakeLists.txt +++ b/src/log_dump/CMakeLists.txt @@ -1,13 +1,18 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(log_dump C) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) +ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/../../include ${CMAKE_SOURCE_DIR}/../../include) +ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE=1) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../../include/) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../) + SET(LOG_DUMP_SRCS log_dump.c dbus-handler.c - ${CMAKE_SOURCE_DIR}/src/shared/util.c - ${CMAKE_SOURCE_DIR}/src/shared/spawn.c - ${CMAKE_SOURCE_DIR}/src/shared/config.c + ${CMAKE_SOURCE_DIR}/../shared/util.c + ${CMAKE_SOURCE_DIR}/../shared/spawn.c + ${CMAKE_SOURCE_DIR}/../shared/config.c ) INCLUDE(FindPkgConfig) @@ -19,7 +24,7 @@ pkg_check_modules(log_dump_pkgs REQUIRED gio-2.0 ) -INCLUDE(${CMAKE_SOURCE_DIR}/cmake/ProcessM4.cmake) +INCLUDE(${CMAKE_SOURCE_DIR}/../../cmake/ProcessM4.cmake) FOREACH(flag ${log_dump_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -- 2.7.4 From 64f5b8a73e16fbaa1b00c99dcb0dec07919fe2ef Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Tue, 10 Sep 2019 14:22:49 +0200 Subject: [PATCH 06/16] Move log_dump to platform/core/system/log_dump Change-Id: I7349a275c370cef32cb6da143acb1b5255de68f3 --- include/defs.h.in | 1 - packaging/crash-worker_system-tests.spec | 3 - packaging/log_dump.manifest | 8 - packaging/log_dump.spec | 62 ---- src/log_dump/CMakeLists.txt | 53 ---- src/log_dump/dbus-handler.c | 238 ---------------- src/log_dump/dbus-handler.h | 26 -- src/log_dump/log_dump.c | 315 --------------------- src/log_dump/log_dump.conf | 26 -- src/log_dump/log_dump.h | 36 --- src/log_dump/log_dump.service.m4 | 11 - src/log_dump/org.tizen.system.crash.service | 4 - tests/system/CMakeLists.txt | 3 - .../log_dump_crash_root_path.sh.template | 31 -- .../log_dump_normal/log_dump_normal.sh.template | 28 -- .../log_dump_short/log_dump_short.sh.template | 32 --- 16 files changed, 877 deletions(-) delete mode 100644 packaging/log_dump.manifest delete mode 100644 packaging/log_dump.spec delete mode 100644 src/log_dump/CMakeLists.txt delete mode 100644 src/log_dump/dbus-handler.c delete mode 100644 src/log_dump/dbus-handler.h delete mode 100644 src/log_dump/log_dump.c delete mode 100644 src/log_dump/log_dump.conf delete mode 100644 src/log_dump/log_dump.h delete mode 100644 src/log_dump/log_dump.service.m4 delete mode 100644 src/log_dump/org.tizen.system.crash.service delete mode 100644 tests/system/log_dump_crash_root_path/log_dump_crash_root_path.sh.template delete mode 100644 tests/system/log_dump_normal/log_dump_normal.sh.template delete mode 100644 tests/system/log_dump_short/log_dump_short.sh.template diff --git a/include/defs.h.in b/include/defs.h.in index a333ff7..3ac9871 100644 --- a/include/defs.h.in +++ b/include/defs.h.in @@ -10,7 +10,6 @@ #define CRASH_STACK_BIN_PATH "@CRASH_STACK_BIN_PATH@" #define CRASH_POPUP_BIN_PATH "@CRASH_POPUP_BIN_PATH@" #define CRASH_NOTIFY_BIN_PATH "@CRASH_NOTIFY_BIN_PATH@" -#define LOG_DUMP_BIN_PATH "@LOG_DUMP_BIN_PATH@" #define DUMP_SYSTEMSTATE_BIN_PATH "@DUMP_SYSTEMSTATE_BIN_PATH@" #define DUMP_SYSTEMSTATE_CONFIG_DIR_PATH "@DUMP_SYSTEMSTATE_CONFIG_DIR_PATH@" #define CRASH_MANAGER_CONFIG_PATH "@CRASH_MANAGER_CONFIG_PATH@" diff --git a/packaging/crash-worker_system-tests.spec b/packaging/crash-worker_system-tests.spec index 2ae412e..2139828 100644 --- a/packaging/crash-worker_system-tests.spec +++ b/packaging/crash-worker_system-tests.spec @@ -66,9 +66,6 @@ cd tests/system %{_libdir}/crash-worker_system-tests/dump_systemstate_extras/dump_systemstate_extras.sh %{_libdir}/crash-worker_system-tests/extra_script/extra_script.sh %{_libdir}/crash-worker_system-tests/info_file/info_file.sh -%{_libdir}/crash-worker_system-tests/log_dump_crash_root_path/log_dump_crash_root_path.sh -%{_libdir}/crash-worker_system-tests/log_dump_normal/log_dump_normal.sh -%{_libdir}/crash-worker_system-tests/log_dump_short/log_dump_short.sh %{_libdir}/crash-worker_system-tests/log_file/log_file.sh %{_libdir}/crash-worker_system-tests/report_basic/report_basic.sh %{_libdir}/crash-worker_system-tests/report_type_info/report_type_info.sh diff --git a/packaging/log_dump.manifest b/packaging/log_dump.manifest deleted file mode 100644 index a340d2e..0000000 --- a/packaging/log_dump.manifest +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/packaging/log_dump.spec b/packaging/log_dump.spec deleted file mode 100644 index ce97c0b..0000000 --- a/packaging/log_dump.spec +++ /dev/null @@ -1,62 +0,0 @@ -Name: log_dump -Summary: log_dump -Version: 5.5.19 -Release: 1 -Group: Framework/system -License: Apache-2.0 and BSD -Source0: %{name}-%{version}.tar.gz -Source1001: log_dump.manifest -Requires: crash-worker -BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(libtzplatform-config) -BuildRequires: pkgconfig(iniparser) -BuildRequires: pkgconfig(capi-system-info) -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: cmake -BuildRequires: pkgconfig(pkgmgr-info) - -%description -log_dump - -%prep -%setup -q - -%define crash_root_path %{TZ_SYS_CRASH_ROOT} -%define crash_all_log %{TZ_SYS_ALLLOGS} -%define crash_dump_gen %{TZ_SYS_DUMPGEN} - -%build -cp %{SOURCE1001} . - -%cmake src/log_dump/ \ - -DCRASH_ROOT_PATH=%{crash_root_path} \ - -DDUMP_SYSTEMSTATE_BIN_PATH=%{_bindir}/dump_systemstate \ - -DCRASH_MANAGER_CONFIG_PATH=%{_sysconfdir}/crash-manager.conf - -make %{?jobs:-j%jobs} - -%install -rm -rf %{buildroot} -%make_install -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}/* - -%post -/usr/bin/chsmack -a "System" -t %{crash_dump_gen} -/usr/bin/chsmack -a "System" -t %{crash_dump_gen}/module.d -/usr/bin/chsmack -a "System::Shared" -t %{crash_all_log} -/usr/bin/chsmack -a "_" %{crash_dump_gen}/module.d/* - -%files -%license LICENSE -%manifest log_dump.manifest -%dir %{crash_all_log} -%{crash_dump_gen}/* -%attr(-,root,root) %{_unitdir}/log_dump.service -%attr(-,root,root) %{_sysconfdir}/dbus-1/system.d/log_dump.conf -%attr(-,root,root) %{_datadir}/dbus-1/system-services/org.tizen.system.crash.service -%attr(0750,system_fw,system_fw) %{_bindir}/log_dump - - diff --git a/src/log_dump/CMakeLists.txt b/src/log_dump/CMakeLists.txt deleted file mode 100644 index cc91ea5..0000000 --- a/src/log_dump/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(log_dump C) - -ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/../../include ${CMAKE_SOURCE_DIR}/../../include) -ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE=1) - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../../include/) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../) - -SET(LOG_DUMP_SRCS - log_dump.c - dbus-handler.c - ${CMAKE_SOURCE_DIR}/../shared/util.c - ${CMAKE_SOURCE_DIR}/../shared/spawn.c - ${CMAKE_SOURCE_DIR}/../shared/config.c - ) - -INCLUDE(FindPkgConfig) -pkg_check_modules(log_dump_pkgs REQUIRED - dlog - capi-system-info - libtzplatform-config - iniparser - gio-2.0 - ) - -INCLUDE(${CMAKE_SOURCE_DIR}/../../cmake/ProcessM4.cmake) - -FOREACH(flag ${log_dump_pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -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} -pie) - -PROCESS_M4("${M4_DEFINES}" - "${CMAKE_CURRENT_SOURCE_DIR}/log_dump.service.m4" - "${CMAKE_CURRENT_SOURCE_DIR}/log_dump.service") - -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.system.crash.service - DESTINATION /usr/share/dbus-1/system-services) - -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/log_dump.conf - DESTINATION /etc/dbus-1/system.d) - -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/log_dump.service DESTINATION /usr/lib/systemd/system - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) - -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 deleted file mode 100644 index 2eecde6..0000000 --- a/src/log_dump/dbus-handler.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * 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 "log_dump.h" -#include "dbus-handler.h" - -/* 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 - -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) -{ - _I("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); - _I("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); - _I("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; - const gchar *arg; - - remove_timeout(); - - 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 - _E("Wrong option for log_dump"); - } else if (g_strcmp0(method_name, "delete_dump") == 0) { - ret = delete_dump(); - } - - 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_OBJECT_PATH, introspection_data->interfaces[0], - &interface_vtable, NULL, NULL, NULL); - if (registration_id == 0) - _E("Failed to g_dbus_connection_register_object"); -} - -static void on_name_acquired(GDBusConnection *conn, - const gchar *name, - gpointer user_data) -{ - _D("Acquired the name %s on the system bus", name); -} - -static void on_name_lost(GDBusConnection *conn, - const gchar *name, - gpointer user_data) -{ - _D("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) { - _E("Failed to init g_dbus_info_new_for_xml"); - return; - } - - conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (!conn) { - _E("Failed to get dbus"); - return; - } - - if (error) { - _E("Failed to get dbus: %s", error->message); - 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(); - - _I("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; -} - -static int broadcast_logdump(const char *signal) -{ - GDBusConnection *conn; - GError *error = NULL; - - _I("broadcast signal: %s", signal); - conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (error) { - _E("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) { - _E("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 deleted file mode 100644 index a936f31..0000000 --- a/src/log_dump/dbus-handler.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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); -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 deleted file mode 100644 index 994ed59..0000000 --- a/src/log_dump/log_dump.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * log_dump: dump current system states - * - * Copyright (c) 2016, 2018 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 - -#include "defs.h" -#include "dbus-handler.h" -#include "log_dump.h" -#include "shared/config.h" -#include "shared/spawn.h" -#include "shared/util.h" - -#define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string" -#define DIR_UMASK 0022 - -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 } -}; - -/* crash worker configuration - for admin-selectable CrashRootPath */ -config_t config; -/* tzplaform vars */ -char *dir_scripts; -/* dynamic vars */ -char *dir_dump; -char *dir_log; -char *dir_debug; -char *dir_temp; // temp rootdir -char *dir_temp_logdump; // rootdir for this log_dump invocation -char *version_string; -/* timestamp */ -const char timestamp_format[] = "%Y%m%d%H%M%S"; -char timestamp_string[20]; /* as per format above */ - -static bool init_temp_dir(char *const temp_root, char **temp_dir) -{ - assert(temp_root); - assert(temp_dir); - - char *template = NULL, *path = NULL; - if (asprintf(&template, "%s/log.XXXXXX", temp_root) > 0) - path = mkdtemp(template); - - if (!path) { - _E("Unable to create temporary directory at mkdtemp(%s): %m", template); - free(template); - return false; - } - - *temp_dir = path; - return true; -} - -static char *crash_root_get(void) -{ - return config.crash_root_path; -} - -static bool init_vars(const char *crash_root) -{ - if (!crash_root) - return false; - - if (asprintf(&dir_log, "%s/log", crash_root) <= 0 - || asprintf(&dir_debug, "%s/debug", crash_root) <= 0 - || asprintf(&dir_dump, "%s/dump", crash_root) <= 0 - || asprintf(&dir_temp, "%s/temp", crash_root) <= 0) - goto fail; - - make_dir(crash_root, "temp", DIR_UMASK); - if (!init_temp_dir(dir_temp, &dir_temp_logdump)) - goto fail; - - make_dir(dir_temp_logdump, "log", DIR_UMASK); - make_dir(crash_root, "debug", DIR_UMASK); - - _D("config: dir_log is %s", dir_log); - _D("config: dir_dump is %s", dir_dump); - _D("config: dir_debug is %s", dir_debug); - _D("config: dir_temp is %s", dir_temp); - _D("config: dir_temp_logdump is %s", dir_temp_logdump); - - dir_scripts = strdup(tzplatform_getenv(TZ_SYS_DUMPGEN)); - _D("config: dir_scripts is %s", dir_scripts); - - if (system_info_get_platform_string(SYSTEM_INFO_KEY_BUILD_STRING, &version_string) != SYSTEM_INFO_ERROR_NONE) { - _W("Failed to system_info_get_platform_string for " SYSTEM_INFO_KEY_BUILD_STRING); - version_string = NULL; - } - _D("version_string is %s", version_string); - - time_t cur_time; - struct tm loc_tm; - cur_time = time(NULL); - localtime_r(&cur_time, &loc_tm); - strftime(timestamp_string, sizeof(timestamp_string), timestamp_format, &loc_tm); - _D("timestamp_string is %s", timestamp_string); - - assert(dir_log); - assert(dir_dump); - assert(dir_debug); - assert(dir_temp); - assert(dir_temp_logdump); - return true; - -fail: - free(dir_log); - free(dir_dump); - free(dir_debug); - free(dir_temp); - free(dir_temp_logdump); - return false; -} - -static void usage(void) -{ - printf("Usage: log_dump {OPTION}\n" - "Options:\n" - " --normal dump all logs (uses scripts from %s)\n" - " --short dump_systemstate logs only\n" - " --dbus become dbus service\n", - dir_scripts); -} - -static bool dump_scripts(char *const workdir, char *const scriptsdir) -{ - struct dirent **dir_list = NULL; - char command[PATH_MAX]; - int script_num, i; - - script_num = scandir(scriptsdir, &dir_list, NULL, NULL); - if (script_num < 0) { - _E("scandir %s: %m", scriptsdir); - return false; - } - - for (i = 0; i < script_num; i++) { - const char *const name = dir_list[i]->d_name; - int type = dir_list[i]->d_type; - - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) - continue; - - if (type != DT_REG) { - _D("Ignoring: not a regular file: %s", name); - continue; - } - snprintf(command, sizeof(command), "%s/%s", scriptsdir, name); - if (access(command, X_OK) != 0) { - _W("Ignoring: file not executable: %s", command); - continue; - } - - _D("Calling scriptlet: %s", command); - - char *const av[] = {command, workdir, NULL}; - (void)spawn_wait(av, NULL, NULL, 0, NULL); - } - - for (i = 0; i < script_num; i++) - free(dir_list[i]); - free(dir_list); - - return true; -} - -static bool dump_systemstate(const char *const destdir, const char *const timestr, int *exit_code) -{ - char *dump_path = NULL; - - if (asprintf(&dump_path, "%s/log/dump_systemstate_%s.log", destdir, timestr) < 0) { - _E("asprintf: %m"); - return false; - } - - char *av[] = {DUMP_SYSTEMSTATE_BIN_PATH, "-k", "-d", "-j", "-e", "-f", dump_path, NULL}; - spawn_param_s param = { .fn = spawn_setstdout, .u.int_val = STDERR_FILENO }; - bool is_ok = spawn_wait(av, NULL, ¶m, 0, exit_code); - - free(dump_path); - - return is_ok; -} - -static bool compress(char *const destdir, char *const tempdir, char *const versionstr, char *const timestr, int *exit_code) -{ - char *archive_path = NULL; - - if (asprintf(&archive_path, "%s/log_dump_%s%s.zip", destdir, versionstr ?: "", timestr) < 0) { - _E("asprintf: %m"); - return false; - } - - _D("compress tempdir is %s", tempdir); - char *av[] = {"/bin/zip", "-qyr", archive_path, ".", NULL}; - spawn_param_s param1 = { .fn = spawn_nullstdfds }; - spawn_param_s param0 = { .fn = spawn_chdir, .u.char_ptr = tempdir, .next = ¶m1 }; - bool is_ok = spawn_wait(av, NULL, ¶m0, 0, exit_code); - - _I("Storing report at %s", archive_path); - - fsync_path(archive_path); - free(archive_path); - - return is_ok; -} - -int log_dump(int option) -{ - broadcast_logdump_start(); - - int ret = -1; - - if (!dump_systemstate(dir_temp_logdump, timestamp_string, NULL)) - goto out; - - if (option == OPT_NORMAL) - (void)dump_scripts(dir_temp_logdump, dir_scripts); - - compress(dir_debug, dir_temp_logdump, version_string, timestamp_string, NULL); - - /* cleanup */ - ret = remove_dir(dir_temp_logdump, 1); - if (ret < 0) - _W("Failed to delete dump directory at %s", dir_temp_logdump); - - ret = 0; -out: - broadcast_logdump_finish(); - - return ret; -} - -int delete_dump(void) -{ - _D("delete_dump called"); - - remove_dir(dir_log, 0); - remove_dir(dir_debug, 1); - remove_dir(dir_dump, 0); - remove_dir(dir_temp, 0); - - return 0; -} - -static void die(void) -{ - usage(); - exit(EXIT_FAILURE); -} - -int main(int argc, char *argv[]) -{ - int c, ret; - int option; - - if (!config_init(&config, CRASH_MANAGER_CONFIG_PATH)) - return false; - - /* need to do this first, because even usage() uses the vars */ - if (!init_vars(crash_root_get())) { - printf("Unable to initialize - please check program logs"); - exit(EXIT_FAILURE); - } - - if (argc < 2) - die(); - - option = -1; - while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) { - if (option >= 0 || c < _OPT_MIN || c > _OPT_MAX) - die(); - option = c; - } - - if (option == OPT_DBUS) - ret = log_dump_dbus(); - else - ret = log_dump(option); - - config_free(&config); - - return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/src/log_dump/log_dump.conf b/src/log_dump/log_dump.conf deleted file mode 100644 index 4c82d0e..0000000 --- a/src/log_dump/log_dump.conf +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/log_dump/log_dump.h b/src/log_dump/log_dump.h deleted file mode 100644 index a6c87c7..0000000 --- a/src/log_dump/log_dump.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * log_dump - * - * Copyright (c) 2016, 2018 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__ - -#define LOG_TAG "LOG_DUMP" -#include "shared/log.h" - -enum { - _OPT_MIN, - OPT_NORMAL = _OPT_MIN, - OPT_SHORT, - OPT_DBUS, - _OPT_MAX = OPT_DBUS, -}; - -int log_dump(int option); -int delete_dump(void); - -#endif diff --git a/src/log_dump/log_dump.service.m4 b/src/log_dump/log_dump.service.m4 deleted file mode 100644 index be46f63..0000000 --- a/src/log_dump/log_dump.service.m4 +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=log_dump service - -[Service] -Type=dbus -BusName=org.tizen.system.crash -ExecStart=/usr/bin/log_dump --dbus -SmackProcessLabel=System -SupplementaryGroups=log systemd-journal -Nice=-5 -KillMode=process diff --git a/src/log_dump/org.tizen.system.crash.service b/src/log_dump/org.tizen.system.crash.service deleted file mode 100644 index 5dfa56b..0000000 --- a/src/log_dump/org.tizen.system.crash.service +++ /dev/null @@ -1,4 +0,0 @@ -[D-BUS Service] -Name=org.tizen.system.crash -Exec=/bin/false -SystemdService=log_dump.service diff --git a/tests/system/CMakeLists.txt b/tests/system/CMakeLists.txt index 767703e..95e4474 100644 --- a/tests/system/CMakeLists.txt +++ b/tests/system/CMakeLists.txt @@ -28,9 +28,6 @@ configure_test("report_basic") configure_test("report_type_info") configure_test("without_core") configure_test("crash_root_path") -configure_test("log_dump_short") -configure_test("log_dump_normal") -configure_test("log_dump_crash_root_path") configure_test("dump_systemstate_extras") configure_test("livedumper") configure_test("extra_script") diff --git a/tests/system/log_dump_crash_root_path/log_dump_crash_root_path.sh.template b/tests/system/log_dump_crash_root_path/log_dump_crash_root_path.sh.template deleted file mode 100644 index aabc739..0000000 --- a/tests/system/log_dump_crash_root_path/log_dump_crash_root_path.sh.template +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Custom report path test - -if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then - CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@" -fi - -. ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh - -tmpdir=$(mktemp -d /tmp/logdump-crash-root-path-test.XXXXXX) - -CRASH_MANAGER_CONF=/etc/crash-manager.conf -mount -o rw,remount / -backup_file ${CRASH_MANAGER_CONF} -sed -ie 's,^CrashRootPath=.*,,g' ${CRASH_MANAGER_CONF} -echo "CrashRootPath=$tmpdir" >> ${CRASH_MANAGER_CONF} - -log_dump --short -logfile="${tmpdir}"/debug/* # there shall be only one file - -check_file_exists "$logfile" - -num=`unzip -qql "$logfile" | wc -l` -if [ $num -ne 2 ]; then - fail "'log_dump --short' report contains $num files - 2 expected" -fi - -restore_file ${CRASH_MANAGER_CONF} - -exit_ok diff --git a/tests/system/log_dump_normal/log_dump_normal.sh.template b/tests/system/log_dump_normal/log_dump_normal.sh.template deleted file mode 100644 index ef70cae..0000000 --- a/tests/system/log_dump_normal/log_dump_normal.sh.template +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Custom report path test - -if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then - CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@" -fi - -. ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh - -clean_logdump -dummy=$(mktemp $CRASH_DUMP_PATH/logdump-normal-test.XXXXXX) - -log_dump --normal -logfile="${LOGDUMP_RESULT_PATH}"/* # there shall be only one file - -check_file_exists "$logfile" -check_zip_contains "$logfile" 'log/dump_systemstate.*log$' -check_zip_contains "$logfile" 'log/system_log/$' -check_zip_contains "$logfile" 'log/system_log/dlog/kernel$' -check_zip_contains "$logfile" 'log/module_log/$' -check_zip_contains "$logfile" 'dump/$' - -check_file_not_exists "$dummy" - -clean_logdump - -exit_ok diff --git a/tests/system/log_dump_short/log_dump_short.sh.template b/tests/system/log_dump_short/log_dump_short.sh.template deleted file mode 100644 index 38d7885..0000000 --- a/tests/system/log_dump_short/log_dump_short.sh.template +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Custom report path test - -if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then - CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@" -fi - -. ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh - -clean_logdump - -dummy=$(mktemp $CRASH_DUMP_PATH/logdump-short-test.XXXXXX) - -log_dump --short -logfile="${LOGDUMP_RESULT_PATH}"/* # there shall be only one file - -check_file_exists "$logfile" - -num=`unzip -qql "$logfile" | wc -l` -if [ $num -ne 2 ]; then - fail "'log_dump --short' report contains $num files - 2 expected" -fi - -check_zip_contains "$logfile" 'log/dump_systemstate.*log$' -check_zip_contains "$logfile" 'log/$' - -check_file_exists "$dummy" - -clean_logdump - -exit_ok -- 2.7.4 From d70d319d3809e38e0c6e42c40944aaf57ce26975 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 26 Sep 2019 21:42:09 +0200 Subject: [PATCH 07/16] Fix compilation on 64-bit architectures 64-bit architetures have lib in lib64, fix this by using cmake-provided information about target system directories. Change-Id: I794c89ad06b7bd80acd50acd3e64a36ffe86ea5d --- packaging/crash-worker.spec | 4 ++-- src/crash-manager/CMakeLists.txt | 6 ++++-- src/crash-service/CMakeLists.txt | 8 +++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 1349392..baa227e 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -247,11 +247,11 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %files devel %{_includedir}/crash-manager.h %{_libdir}/libcrash-manager.so -%{_datadir}/pkgconfig/crash-manager.pc +%{_libdir}/pkgconfig/crash-manager.pc %if %{with crashservice} %{_includedir}/libcrash-service.h %{_libdir}/libcrash-service.so -%{_datadir}/pkgconfig/crash-service.pc +%{_libdir}/pkgconfig/crash-service.pc %endif %if %{with doc} diff --git a/src/crash-manager/CMakeLists.txt b/src/crash-manager/CMakeLists.txt index b935621..b38a084 100644 --- a/src/crash-manager/CMakeLists.txt +++ b/src/crash-manager/CMakeLists.txt @@ -14,6 +14,8 @@ SET(CRASH_MANAGER_SRCS main.c ) +INCLUDE(GNUInstallDirs) + INCLUDE(FindPkgConfig) pkg_check_modules(crash-manager_pkgs REQUIRED dlog @@ -53,7 +55,7 @@ ADD_EXECUTABLE(${CRASH_NOTIFY} dbus_notify.c) TARGET_LINK_LIBRARIES(${CRASH_NOTIFY} ${helper_pkgs_LDFLAGS} -pie) install(TARGETS ${CRASH_NOTIFY} DESTINATION libexec) -INSTALL(TARGETS libcrash-manager LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include) +INSTALL(TARGETS libcrash-manager LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE @@ -68,7 +70,7 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.conf PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.pc - DESTINATION share/pkgconfig + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/70-${PROJECT_NAME}.conf diff --git a/src/crash-service/CMakeLists.txt b/src/crash-service/CMakeLists.txt index 37ad6b1..a8de738 100644 --- a/src/crash-service/CMakeLists.txt +++ b/src/crash-service/CMakeLists.txt @@ -7,6 +7,8 @@ SET(CRASH_SERVICE_SRCS crash-service.c ) +INCLUDE(GNUInstallDirs) + INCLUDE(FindPkgConfig) pkg_check_modules(crash-service_pkgs REQUIRED @@ -53,8 +55,8 @@ INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -INSTALL(TARGETS libcrash-service LIBRARY DESTINATION /usr/lib/ - PUBLIC_HEADER DESTINATION /usr/include) +INSTALL(TARGETS libcrash-service LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/crash-service.pc - DESTINATION share/pkgconfig) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) -- 2.7.4 From 766b8791820c94ff8cff56bfa5f6a953ce9c9f57 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Sat, 28 Sep 2019 18:28:01 +0200 Subject: [PATCH 08/16] Make remaining macros behave like standard statements Change-Id: Id09a320422eeac2ddd459b47b023df8d4d975971 --- src/crash-manager/crash-manager.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index dd2bab1..821d516 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -534,7 +534,7 @@ end: } // These macros are used in functions below -#define SNPRINTF_OR_EXIT_W(name, format, member) if (snprintf(name##_str, sizeof(name##_str), format, cinfo->member) < 0) goto out; +#define SNPRINTF_OR_EXIT_W(name, format, member) do { if (snprintf(name##_str, sizeof(name##_str), format, cinfo->member) < 0) goto out; } while (0) #define SNPRINTF_OR_EXIT(name, format) SNPRINTF_OR_EXIT_W(name, format, name##_info) static bool extra_script(const struct crash_info *cinfo, pid_t *pid) @@ -543,7 +543,7 @@ static bool extra_script(const struct crash_info *cinfo, pid_t *pid) return false; char pid_str[11]; - SNPRINTF_OR_EXIT(pid, "%d") + SNPRINTF_OR_EXIT(pid, "%d"); char *av[] = { config.extra_script, cinfo->pfx, pid_str, NULL }; spawn_param_s param = { .fn = spawn_setstdout, .u.int_val = STDERR_FILENO }; @@ -568,9 +568,9 @@ static void launch_dbus_notify(struct crash_info *cinfo) return; } - SNPRINTF_OR_EXIT(pid, "%d") - SNPRINTF_OR_EXIT(tid, "%d") - SNPRINTF_OR_EXIT(sig, "%d") + SNPRINTF_OR_EXIT(pid, "%d"); + SNPRINTF_OR_EXIT(tid, "%d"); + SNPRINTF_OR_EXIT(sig, "%d"); char *av[] = { CRASH_NOTIFY_BIN_PATH, "--cmdline", cinfo->cmd_line, @@ -604,11 +604,11 @@ static bool execute_minicoredump(struct crash_info *cinfo, int *exit_code) char pid_str[11], uid_str[11], gid_str[11], sig_str[11], time_str[11]; - SNPRINTF_OR_EXIT(pid, "%d") - SNPRINTF_OR_EXIT(uid, "%d") - SNPRINTF_OR_EXIT(gid, "%d") - SNPRINTF_OR_EXIT(sig, "%d") - SNPRINTF_OR_EXIT(time, "%ld") + SNPRINTF_OR_EXIT(pid, "%d"); + SNPRINTF_OR_EXIT(uid, "%d"); + SNPRINTF_OR_EXIT(gid, "%d"); + SNPRINTF_OR_EXIT(sig, "%d"); + SNPRINTF_OR_EXIT(time, "%ld"); /* Execute minicoredumper */ char *args[] = { @@ -664,7 +664,7 @@ static bool execute_livedumper(const struct crash_info *cinfo, int *exit_code) goto out; } - SNPRINTF_OR_EXIT(pid, "%d") + SNPRINTF_OR_EXIT(pid, "%d"); /* Execute livedumper */ char *args[] = { @@ -689,10 +689,10 @@ static bool execute_crash_stack(const struct crash_info *cinfo, int *exit_code) char pid_str[11], tid_str[11], sig_str[11], prstatus_fd_str[11]; bool is_ok = false; - SNPRINTF_OR_EXIT(pid, "%d") - SNPRINTF_OR_EXIT(tid, "%d") - SNPRINTF_OR_EXIT(sig, "%d") - SNPRINTF_OR_EXIT_W(prstatus_fd, "%d", prstatus_fd) + SNPRINTF_OR_EXIT(pid, "%d"); + SNPRINTF_OR_EXIT(tid, "%d"); + SNPRINTF_OR_EXIT(sig, "%d"); + SNPRINTF_OR_EXIT_W(prstatus_fd, "%d", prstatus_fd); /* Execute crash-stack */ char *args[] = { CRASH_STACK_BIN_PATH, -- 2.7.4 From a9dc259e856b43cfc7dd0ca746d4acefa41ed68b Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Thu, 3 Oct 2019 17:46:29 +0200 Subject: [PATCH 09/16] Initialize variables to NULL Change-Id: I8d9abdea13e0a11ac3c0b55386a137f095767803 --- src/crash-manager/crash-manager.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 821d516..9714a6d 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -1111,6 +1111,11 @@ void crash_info_init(struct crash_info *cinfo) cinfo->result_path = NULL; cinfo->info_path = NULL; cinfo->core_path = NULL; + cinfo->log_path = NULL; + +#ifdef SYS_ASSERT + cinfo->sysassert_cs_path = NULL; +#endif } static bool run(struct crash_info *cinfo) -- 2.7.4 From 6310e478f66c2a4dfb917352cba8a4a0b7fd6bf2 Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Wed, 9 Oct 2019 10:26:06 +0200 Subject: [PATCH 10/16] Fix coverity issue - ensure that the buffer is null terminated Change-Id: Ia5eb44790320f48f6751aa247d1d600cb01a9f10 --- src/livedumper/core.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/livedumper/core.hpp b/src/livedumper/core.hpp index bd1737c..54bcf9b 100644 --- a/src/livedumper/core.hpp +++ b/src/livedumper/core.hpp @@ -462,6 +462,7 @@ class Core { char buff[PAGESIZE]; ReadFromFile(mem_fd, addr, buff, sizeof(buff)); + buff[sizeof(buff)-1] = 0; if (buff[0] != 0) { DumpData(mem_fd, core_file, addr, strnlen(buff, sizeof(buff)) + 1, "l_name"); -- 2.7.4 From 71bcf454717466db773f582d52180c81ca554f06 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 26 Sep 2019 14:36:31 +0200 Subject: [PATCH 11/16] Release 5.5.23 This release drops log_dump, which is moved to separate repository. Change-Id: I305f4a758721c1b5566aa61693d2ad65ad281a5a --- packaging/crash-worker.spec | 2 +- packaging/crash-worker_system-tests.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 2d550a9..24c7ae8 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -14,7 +14,7 @@ Name: crash-worker Summary: Crash-manager -Version: 5.5.22 +Version: 5.5.23 Release: 1 Group: Framework/system License: Apache-2.0 and BSD diff --git a/packaging/crash-worker_system-tests.spec b/packaging/crash-worker_system-tests.spec index 2139828..300407f 100644 --- a/packaging/crash-worker_system-tests.spec +++ b/packaging/crash-worker_system-tests.spec @@ -8,7 +8,7 @@ Name: crash-worker_system-tests Summary: Package with binaries and scripts for crash-worker system tests -Version: 5.5.22 +Version: 5.5.23 Release: 1 Group: Framework/system License: Apache-2.0 and BSD -- 2.7.4 From 4fbd0e00d80224d866bc9d18c7979251a8be454a Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 10 Oct 2019 13:03:58 +0200 Subject: [PATCH 12/16] Drop log_dump scripts Change-Id: I9adf5d9cca48a3313338c881ee3227beb32880a3 --- dump_scripts/module_log.sh | 19 ------------------- dump_scripts/move_dump.sh | 12 ------------ dump_scripts/system_log.sh | 12 ------------ 3 files changed, 43 deletions(-) delete mode 100755 dump_scripts/module_log.sh delete mode 100755 dump_scripts/move_dump.sh delete mode 100755 dump_scripts/system_log.sh diff --git a/dump_scripts/module_log.sh b/dump_scripts/module_log.sh deleted file mode 100755 index 4c73e33..0000000 --- a/dump_scripts/module_log.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# -# Dump module log -# -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -DUMP_DEST=$1/log/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/move_dump.sh b/dump_scripts/move_dump.sh deleted file mode 100755 index 94d09c4..0000000 --- a/dump_scripts/move_dump.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -. /etc/tizen-platform.conf - -set -ex - -DEST="$1/dump" -mkdir -p "$DEST" -mv -f "${TZ_SYS_CRASH}"/* "$DEST"/ - diff --git a/dump_scripts/system_log.sh b/dump_scripts/system_log.sh deleted file mode 100755 index 36beeb1..0000000 --- a/dump_scripts/system_log.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# -# Dump system log -# -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -DUMP_DEST=$1/log/system_log - -mkdir -p ${DUMP_DEST} - -/bin/cp -fr /opt/var/log/* ${DUMP_DEST} -/bin/cp -fr /run/systemd/journal ${DUMP_DEST} -- 2.7.4 From 4b6000683c26c4fa289d6821a79431d5c3739911 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 10 Oct 2019 13:30:03 +0200 Subject: [PATCH 13/16] upgrade script: change confusing comments Change-Id: I50c6ef0195a63f39ebbf40cbe68cccca4bad7f83 --- src/crash-manager/500.crash-manager-upgrade.sh.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crash-manager/500.crash-manager-upgrade.sh.in b/src/crash-manager/500.crash-manager-upgrade.sh.in index 63b2d3f..ac4141f 100644 --- a/src/crash-manager/500.crash-manager-upgrade.sh.in +++ b/src/crash-manager/500.crash-manager-upgrade.sh.in @@ -1,12 +1,12 @@ #!/bin/sh #----------------------------------------------# -# crash-manager patch for upgrade (2.4 -> 3.0) # +# crash-manager patch for upgrade (5.0 -> 5.5) # #----------------------------------------------# PATH=/bin:/usr/bin:/sbin:/usr/sbin -rm -rf /opt/usr/share/crash # Crash path of Tizen 2.4 +rm -rf /opt/usr/share/crash # Crash path of Tizen 5.0 mkdir -p @CRASH_ROOT_PATH@ mkdir -p @CRASH_TEMP@ -- 2.7.4 From 4611af50d6db1dd8ee089cb3d3846c82d8fffd90 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 10 Oct 2019 13:31:58 +0200 Subject: [PATCH 14/16] Drop sys-assert It's been deprecated for long time. Change-Id: I0f5623cbf2ef32c9630d853ead61a6e92bfa27b2 --- packaging/crash-worker.spec | 29 -- src/crash-manager/crash-manager.c | 58 --- src/sys-assert/CMakeLists.txt | 64 --- src/sys-assert/arm/backtrace.c | 48 -- src/sys-assert/arm/context.c | 60 --- src/sys-assert/arm_64/backtrace.c | 48 -- src/sys-assert/arm_64/context.c | 94 ---- src/sys-assert/sys-assert.c | 851 ----------------------------------- src/sys-assert/sys-assert.conf.in | 2 - src/sys-assert/sys-assert.h | 61 --- src/sys-assert/util.c | 118 ----- src/sys-assert/util.h | 30 -- src/sys-assert/x86/backtrace.c | 56 --- src/sys-assert/x86/context.c | 56 --- src/sys-assert/x86/sys-assert-regs.h | 99 ---- 15 files changed, 1674 deletions(-) delete mode 100644 src/sys-assert/CMakeLists.txt delete mode 100644 src/sys-assert/arm/backtrace.c delete mode 100644 src/sys-assert/arm/context.c delete mode 100644 src/sys-assert/arm_64/backtrace.c delete mode 100644 src/sys-assert/arm_64/context.c delete mode 100644 src/sys-assert/sys-assert.c delete mode 100644 src/sys-assert/sys-assert.conf.in delete mode 100755 src/sys-assert/sys-assert.h delete mode 100644 src/sys-assert/util.c delete mode 100644 src/sys-assert/util.h delete mode 100644 src/sys-assert/x86/backtrace.c delete mode 100644 src/sys-assert/x86/context.c delete mode 100644 src/sys-assert/x86/sys-assert-regs.h diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 24c7ae8..fc64bba 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -5,7 +5,6 @@ %define _with_livedumper on %define _with_crashservice on %bcond_with doc -%bcond_with sys_assert %bcond_with tests %bcond_with livedumper %bcond_with crashservice @@ -133,7 +132,6 @@ export CFLAGS+=" -Werror" -DCRASH_POPUP_BIN_PATH=%{_libexecdir}/crash-popup-launch \ -DCRASH_NOTIFY_BIN_PATH=%{_libexecdir}/crash-notify-send \ -DCRASH_TESTS_PATH=%{_libdir}/crash-worker-tests \ - -DSYS_ASSERT=%{on_off sys_assert} \ -DLIVEDUMPER=%{on_off livedumper} \ -DCRASH_SERVICE=%{on_off crashservice} \ -DUPGRADE_SCRIPT_PATH=%{upgrade_script_path} \ @@ -153,31 +151,9 @@ mkdir -p %{buildroot}%{crash_path} mkdir -p %{buildroot}%{crash_temp} %post -%if %{with sys_assert} -if [ ! -d /.build ]; then - orig="%{_libdir}/libsys-assert.so" - pattern=$(echo $orig | sed -e 's|/|\\/|g') - ret=$(sed -n "/${pattern}/p" %{_sysconfdir}/ld.so.preload) - if [ -z "$ret" ]; then - echo "%{_libdir}/libsys-assert.so" >> %{_sysconfdir}/ld.so.preload - fi - chmod 644 %{_sysconfdir}/ld.so.preload -fi - -/sbin/ldconfig -%endif - /usr/bin/chsmack -a "System" -t %{crash_path} /usr/bin/chsmack -a "System" -t %{crash_temp} -%postun -%if %{with sys_assert} -orig="%{_libdir}/libsys-assert.so" -pattern=$(echo $orig | sed -e 's|/|\\/|g') -sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload -/sbin/ldconfig -%endif - %files %license LICENSE LICENSE.BSD %manifest crash-worker.manifest @@ -204,11 +180,6 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %{_libdir}/libcrash-service.so.* %endif -%if %{with sys_assert} -%{_libdir}/libsys-assert.so -%{_sysconfdir}/tmpfiles.d/sys-assert.conf -%endif - #upgrade script %attr(-,root,root) %{upgrade_script_path}/500.crash-manager-upgrade.sh diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 9714a6d..a96342e 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -411,14 +411,6 @@ bool set_crash_info(struct crash_info *cinfo) goto rm_temp; } -#ifdef SYS_ASSERT - if (asprintf(&cinfo->sysassert_cs_path, "/tmp/crash_stack/%s_%d.info", - basename(cinfo->cmd_line), cinfo->pid_info) == -1) { - _E("Failed to snprintf for sys-assert callstack path"); - cinfo->sysassert_cs_path = NULL; - goto rm_temp; - } -#endif if (set_prstatus(cinfo) < 0) goto rm_temp; @@ -437,37 +429,6 @@ rm_temp: return false; } -#ifdef SYS_ASSERT -static int get_sysassert_cs(struct crash_info *cinfo) -{ - int ret; - char move_path[PATH_MAX]; - - if (access(cinfo->sysassert_cs_path, F_OK)) { - _E("The sys-assert cs file not found: %s: %m", - cinfo->sysassert_cs_path); - cinfo->have_sysassert_report = 0; - return -1; - } else - cinfo->have_sysassert_report = 1; - - ret = snprintf(move_path, sizeof(move_path), "%s/%s", - cinfo->pfx, basename(cinfo->sysassert_cs_path)); - if (ret < 0) { - _E("Failed to snprintf for move path"); - return -1; - } - - if (move_file(move_path, cinfo->sysassert_cs_path) < 0) { - _E("Failed to move %s to %s", - cinfo->sysassert_cs_path, move_path); - return -1; - } - - return 0; -} -#endif - static void launch_crash_popup(struct crash_info *cinfo) { assert(cinfo); @@ -767,12 +728,6 @@ static bool execute_crash_modules(struct crash_info *cinfo) } } -#ifdef SYS_ASSERT - /* Use process_vm_readv() version as fallback if sys-assert - * failed to generate report */ - if (cinfo->have_sysassert_report) - return false; -#endif execute_crash_stack(cinfo, NULL); if (cinfo->livedump) process_continue(cinfo->pid_info); @@ -1089,10 +1044,6 @@ static void free_crash_info(struct crash_info *cinfo) free(cinfo->info_path); free(cinfo->core_path); free(cinfo->log_path); - -#ifdef SYS_ASSERT - free(cinfo->sysassert_cs_path); -#endif } void crash_info_init(struct crash_info *cinfo) @@ -1112,10 +1063,6 @@ void crash_info_init(struct crash_info *cinfo) cinfo->info_path = NULL; cinfo->core_path = NULL; cinfo->log_path = NULL; - -#ifdef SYS_ASSERT - cinfo->sysassert_cs_path = NULL; -#endif } static bool run(struct crash_info *cinfo) @@ -1124,11 +1071,6 @@ static bool run(struct crash_info *cinfo) static pid_t dump_state_pid = 0, extra_script_pid = 0; int debug_mode = access(DEBUGMODE_PATH, F_OK) == 0; -#ifdef SYS_ASSERT - /* Fetch callstack of sys-assert */ - get_sysassert_cs(cinfo); -#endif - if (config.report_type >= REP_TYPE_FULL) { /* Exec dump_systemstate */ if (!dump_system_state(cinfo, &dump_state_pid)) { diff --git a/src/sys-assert/CMakeLists.txt b/src/sys-assert/CMakeLists.txt deleted file mode 100644 index 99d3383..0000000 --- a/src/sys-assert/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -SET(LIBNAME sys-assert) -SET(SRCS - sys-assert.c - util.c -) - -#arm -IF("${ARCH}" STREQUAL "arm") -IF("${ARCH_BIT}" STREQUAL "32") - SET(SRCS ${SRCS} - arm/context.c - arm/backtrace.c - ) -ENDIF("${ARCH_BIT}" STREQUAL "32") -IF("${ARCH_BIT}" STREQUAL "64") - SET(SRCS ${SRCS} - arm_64/context.c - arm_64/backtrace.c - ) -ENDIF("${ARCH_BIT}" STREQUAL "64") -ADD_DEFINITIONS("-DARCH_ARM") -ENDIF("${ARCH}" STREQUAL "arm") - -#x86 -IF("${ARCH}" STREQUAL "x86") - SET(SRCS ${SRCS} - x86/context.c - x86/backtrace.c - ) -ENDIF("${ARCH}" STREQUAL "x86") - -IF("${ARCH_BIT}" STREQUAL "64") -ADD_DEFINITIONS("-DARCH_64") -ENDIF("${ARCH_BIT}" STREQUAL "64") - -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -INCLUDE(FindPkgConfig) -pkg_check_modules(sys-assert_pkgs REQUIRED libtzplatform-config libunwind) - -FOREACH(flag ${sys-assert_pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") -SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") -SET(CMAKE_C_FLAGS_RELEASE "-O2") - -FIND_PROGRAM(UNAME NAMES uname) -EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") -IF("${ARCH}" STREQUAL "arm") - ADD_DEFINITIONS("-DTARGET") - MESSAGE("add -DTARGET") -ENDIF("${ARCH}" STREQUAL "arm") - -ADD_LIBRARY(${LIBNAME} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES(${LIBNAME} ${sys-assert_pkgs_LDFLAGS} -ldl) - -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}) diff --git a/src/sys-assert/arm/backtrace.c b/src/sys-assert/arm/backtrace.c deleted file mode 100644 index 2d1241a..0000000 --- a/src/sys-assert/arm/backtrace.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include "util.h" - -int dump_callstack(void **callstack_addrs, int size, void *context, int retry) -{ - ucontext_t *ucontext = context; - int count; - - if (!callstack_addrs) - return 0; - - if (!retry && (context && ((int)ucontext->uc_mcontext.arm_pc != 0))) - count = unw_backtrace(callstack_addrs, size); - else - count = backtrace(callstack_addrs, size); - - if (count > CALLSTACK_BASE) { - count -= CALLSTACK_BASE; - } else if (context) { - callstack_addrs[CALLSTACK_BASE] = (long *)ucontext->uc_mcontext.arm_pc; - callstack_addrs[CALLSTACK_BASE] = (long *)ucontext->uc_mcontext.arm_lr; - count = 2; - } else { - count = 0; - } - return count; -}; diff --git a/src/sys-assert/arm/context.c b/src/sys-assert/arm/context.c deleted file mode 100644 index ec59f9e..0000000 --- a/src/sys-assert/arm/context.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "sys-assert.h" -#include "util.h" - -#define CRASH_REGISTERINFO_TITLE "Register Information" - -void dump_registers(int fd, void *context) -{ - ucontext_t *ucontext = context; - /* for context info */ - if (!context) - return; - - fprintf_fd(fd, "\n%s\n", CRASH_REGISTERINFO_TITLE); - fprintf_fd(fd, - "r0 = 0x%08x, r1 = 0x%08x\nr2 = 0x%08x, r3 = 0x%08x\n", - ucontext->uc_mcontext.arm_r0, - ucontext->uc_mcontext.arm_r1, - ucontext->uc_mcontext.arm_r2, - ucontext->uc_mcontext.arm_r3); - fprintf_fd(fd, - "r4 = 0x%08x, r5 = 0x%08x\nr6 = 0x%08x, r7 = 0x%08x\n", - ucontext->uc_mcontext.arm_r4, - ucontext->uc_mcontext.arm_r5, - ucontext->uc_mcontext.arm_r6, - ucontext->uc_mcontext.arm_r7); - fprintf_fd(fd, - "r8 = 0x%08x, r9 = 0x%08x\nr10 = 0x%08x, fp = 0x%08x\n", - ucontext->uc_mcontext.arm_r8, - ucontext->uc_mcontext.arm_r9, - ucontext->uc_mcontext.arm_r10, - ucontext->uc_mcontext.arm_fp); - fprintf_fd(fd, - "ip = 0x%08x, sp = 0x%08x\nlr = 0x%08x, pc = 0x%08x\n", - ucontext->uc_mcontext.arm_ip, - ucontext->uc_mcontext.arm_sp, - ucontext->uc_mcontext.arm_lr, - ucontext->uc_mcontext.arm_pc); - fprintf_fd(fd, "cpsr = 0x%08x\n", - ucontext->uc_mcontext.arm_cpsr); -}; diff --git a/src/sys-assert/arm_64/backtrace.c b/src/sys-assert/arm_64/backtrace.c deleted file mode 100644 index 21a10d4..0000000 --- a/src/sys-assert/arm_64/backtrace.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include "util.h" - -int dump_callstack(void **callstack_addrs, int size, void *context, int retry) -{ - ucontext_t *ucontext = context; - int count; - - if (!callstack_addrs) - return 0; - - if (!retry && (context && ((int)ucontext->uc_mcontext.pc != 0))) - count = unw_backtrace(callstack_addrs, size); - else - count = backtrace(callstack_addrs, size); - - if (count > CALLSTACK_BASE) { - count -= CALLSTACK_BASE; - } else if (context) { - callstack_addrs[CALLSTACK_BASE] = (long *)ucontext->uc_mcontext.pc; - callstack_addrs[CALLSTACK_BASE] = (long *)ucontext->uc_mcontext.regs[30]; /* LR (link register) */ - count = 2; - } else { - count = 0; - } - return count; -}; diff --git a/src/sys-assert/arm_64/context.c b/src/sys-assert/arm_64/context.c deleted file mode 100644 index 9416eb8..0000000 --- a/src/sys-assert/arm_64/context.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "sys-assert.h" -#include "util.h" - -#define CRASH_REGISTERINFO_TITLE "Register Information" - -void dump_registers(int fd, void *context) -{ - ucontext_t *ucontext = context; - - /* for context info */ - if (!context) - return; - - fprintf_fd(fd, "\n%s\n", CRASH_REGISTERINFO_TITLE); - fprintf_fd(fd, - "x0 = 0x%08x, x1 = 0x%08x\nx2 = 0x%08x, x3 = 0x%08x\n", - ucontext->uc_mcontext.regs[0], - ucontext->uc_mcontext.regs[1], - ucontext->uc_mcontext.regs[2], - ucontext->uc_mcontext.regs[3]); - fprintf_fd(fd, - "x4 = 0x%08x, x5 = 0x%08x\nx6 = 0x%08x, x7 = 0x%08x\n", - ucontext->uc_mcontext.regs[4], - ucontext->uc_mcontext.regs[5], - ucontext->uc_mcontext.regs[6], - ucontext->uc_mcontext.regs[7]); - fprintf_fd(fd, - "x8 = 0x%08x, x9 = 0x%08x\nx10 = 0x%08x, x11 = 0x%08x\n", - ucontext->uc_mcontext.regs[8], - ucontext->uc_mcontext.regs[9], - ucontext->uc_mcontext.regs[10], - ucontext->uc_mcontext.regs[11]); - fprintf_fd(fd, - "x12 = 0x%08x, x13 = 0x%08x\nx14 = 0x%08x, x15 = 0x%08x\n", - ucontext->uc_mcontext.regs[12], - ucontext->uc_mcontext.regs[13], - ucontext->uc_mcontext.regs[14], - ucontext->uc_mcontext.regs[15]); - fprintf_fd(fd, - "x16 = 0x%08x, x17 = 0x%08x\nx18 = 0x%08x, x19 = 0x%08x\n", - ucontext->uc_mcontext.regs[16], - ucontext->uc_mcontext.regs[17], - ucontext->uc_mcontext.regs[18], - ucontext->uc_mcontext.regs[19]); - fprintf_fd(fd, - "x20 = 0x%08x, x21 = 0x%08x\nx22 = 0x%08x, x23 = 0x%08x\n", - ucontext->uc_mcontext.regs[20], - ucontext->uc_mcontext.regs[21], - ucontext->uc_mcontext.regs[22], - ucontext->uc_mcontext.regs[23]); - fprintf_fd(fd, - "x24 = 0x%08x, x25 = 0x%08x\nx26 = 0x%08x, x27 = 0x%08x\n", - ucontext->uc_mcontext.regs[24], - ucontext->uc_mcontext.regs[25], - ucontext->uc_mcontext.regs[26], - ucontext->uc_mcontext.regs[27]); - fprintf_fd(fd, - "x28 = 0x%08x, x29 = 0x%08x\nx30 = 0x%08x\n", - ucontext->uc_mcontext.regs[28], - ucontext->uc_mcontext.regs[29], - ucontext->uc_mcontext.regs[30]); - fprintf_fd(fd, - "xr = 0x%08x, ip0 = 0x%08x\nip1 = 0x%08x, pr = 0x%08x\n", - ucontext->uc_mcontext.regs[8], /* Indirect result location register */ - ucontext->uc_mcontext.regs[16], /* Intra-procedure call scratch register 0 */ - ucontext->uc_mcontext.regs[17], /* Intra-procedure call scratch register 1 */ - ucontext->uc_mcontext.regs[18]); /* Platform register */ - fprintf_fd(fd, - "fp = 0x%08x, lr = 0x%08x\npc = 0x%08x, sp = 0x%08x\n", - ucontext->uc_mcontext.regs[29], /* Frame register */ - ucontext->uc_mcontext.regs[30], /* Procedure link register */ - ucontext->uc_mcontext.pc, /* Program counter */ - ucontext->uc_mcontext.sp); /* Stack pointer */ -}; diff --git a/src/sys-assert/sys-assert.c b/src/sys-assert/sys-assert.c deleted file mode 100644 index 5af44ff..0000000 --- a/src/sys-assert/sys-assert.c +++ /dev/null @@ -1,851 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sys-assert.h" -#include "util.h" - -#define CMDLINE_PATH "/proc/self/cmdline" -#define EXE_PATH "/proc/self/exe" -#define MAPS_PATH "/proc/self/maps" -#define MEMINFO_PATH "/proc/meminfo" -#define VERINFO_PATH "/etc/info.ini" -#define STATUS_PATH "/proc/self/status" -#define TASK_PATH "/proc/self/task" - -#define CRASH_INFO_PATH "/tmp/crash_stack" -#define CRASH_SOCKET "/tmp/crash_socket" -#define CRASH_SOCKET_PATH_LEN 17 - -#define CRASH_CALLSTACKINFO_TITLE "Callstack Information" -#define CRASH_CALLSTACKINFO_TITLE_E "End of Call Stack" -#define CRASH_MAPSINFO_TITLE "Maps Information" -#define CRASH_MAPSINFO_TITLE_E "End of Maps Information" -#define CRASH_MEMINFO_TITLE "Memory Information" -#define CRASH_THREADINFO_TITLE "Threads Information" - -#define STR_ANONY "[anony]" -#define STR_ANNOY_LEN 8 - -#define HEXA 16 -#define PERM_LEN 5 -#define PERM_LEN_DEC 4 -#ifdef ARCH_64 -#define ADDR_LEN 10 -#define ADDR_BUF_LEN 22 -#define ADDR_BUF_LEN_DEC 21 -#else -#define ADDR_LEN 8 -#define ADDR_BUF_LEN 18 -#define ADDR_BUF_LEN_DEC 17 -#endif -#define INFO_LEN 20 -#define INFO_LEN_DEC 19 -#define VALUE_LEN 24 -#define VALUE_LEN_DEC 23 -#define TIME_MAX_LEN 64 -#define FILE_LEN 255 -#define BUF_SIZE (BUFSIZ) -#define CALLSTACK_SIZE 100 -#define FUNC_NAME_MAX_LEN 128 -#define PATH_LEN (FILE_LEN + NAME_MAX) - -#define STRING_FORMAT_SPECIFIER_WITH_MACRO(macro) "%"#macro"s" -#define STR_FS(macro) STRING_FORMAT_SPECIFIER_WITH_MACRO(macro) - -#define KB(bytes) ((bytes)/1024) - -/* permission for open file */ -#define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) -/* permission for open file */ -#define FILE_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) - -int sig_to_handle[] = { - SIGILL, SIGTRAP, SIGABRT, SIGBUS, - SIGFPE, SIGSTKFLT, SIGXCPU, SIGXFSZ, SIGSYS }; - -#define NUM_SIG_TO_HANDLE \ - ((int)(sizeof(sig_to_handle)/sizeof(sig_to_handle[0]))) - -struct sigaction g_oldact[NUM_SIG_TO_HANDLE]; - -extern void dump_registers(int fd, void *context); -extern int dump_callstack(void **callstack_addrs, int size, void *context, int retry); - -/* get function symbol from elf */ -static int trace_symbols(void *const *array, int size, struct addr_node *start, int fd) -{ - Dl_info info_funcs; - Elf32_Ehdr elf_h = {{0, }, 0, }; - Elf32_Shdr *s_headers; - Elf32_Sym *symtab_entry; - int i, cnt, file, ret; - char *fname; - unsigned long addr, start_addr, offset_addr; - unsigned int strtab_index = 0; - unsigned int symtab_index = 0; - int num_st = 0; - int found_symtab = 0; - int is_mapped = 0; - - for (cnt = 0; cnt < size; cnt++) { - num_st = 0; - /* FIXME : for walking on stack trace */ - if (dladdr(array[cnt], &info_funcs) == 0) { - fprintf(stderr, "[sys-assert]dladdr returnes error!\n"); - /* print just address */ - fprintf_fd(fd, - "%2d: (%p) %s\n", - cnt, array[cnt], dlerror()); - continue; - } - start_addr = (unsigned long)get_start_addr(array[cnt], start); - addr = (unsigned long)array[cnt]; - /* because of launchpad, - * return value of dladdr when find executable is wrong. - * so fix dli_fname here */ - if (info_funcs.dli_fbase && - info_funcs.dli_fname && - info_funcs.dli_fbase == (void *)BASE_LAUNCHPAD_ADDR && - (strncmp("/opt/apps/", info_funcs.dli_fname, - strlen("/opt/apps/")) == 0)) { - info_funcs.dli_fname = get_fpath(array[cnt], start); - offset_addr = addr; - } else { - offset_addr = addr - start_addr; - } - - /* find symbol from elf file */ - if (info_funcs.dli_sname == NULL) { - - /* Both dli_sname and dli_fname is NULL, sys-assert cannot trace any information. - Thus, sys-assert skips to translate such address entry. - However, if a developer wants raw information, we need to fix the code to print raw data */ - if (info_funcs.dli_fname == NULL) - continue; - - file = open(info_funcs.dli_fname, O_RDONLY); - if (file < 0) { - fname = strchr(info_funcs.dli_fname, '/'); - if (!fname) - continue; - file = open(fname, O_RDONLY); - if (file < 0) { - fprintf_fd(fd, - "%2d: (%p) [%s] + %p\n", - cnt, array[cnt], - info_funcs.dli_fname, offset_addr); - continue; - } - } - ret = read(file, &elf_h, sizeof(Elf32_Ehdr)); - if (ret < sizeof(Elf32_Ehdr) || - elf_h.e_shnum <= 0 || - SHN_LORESERVE < elf_h.e_shnum) { - fprintf_fd(fd, "%2d: (%p) [%s] + %p\n", - cnt, array[cnt], info_funcs.dli_fname, offset_addr); - close(file); - continue; - } - if (elf_h.e_type == ET_EXEC) { - info_funcs.dli_fbase = 0; - offset_addr = addr; - } - s_headers = - (Elf32_Shdr *) mmap(0, elf_h.e_shnum * sizeof(Elf32_Shdr), - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (s_headers == NULL) { - fprintf(stderr, "[sys-assert]malloc failed\n"); - fprintf_fd(fd, "%2d: (%p) [%s] + %p\n", - cnt, array[cnt], info_funcs.dli_fname, offset_addr); - close(file); - continue; - } - ret = lseek(file, elf_h.e_shoff, SEEK_SET); - if (ret < 0 || elf_h.e_shentsize > sizeof(Elf32_Shdr) || - elf_h.e_shentsize <= 0) { - close(file); - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - return -1; - } - for (i = 0; i < elf_h.e_shnum; i++) { - ret = read(file, &s_headers[i], elf_h.e_shentsize); - if (ret < elf_h.e_shentsize) { - fprintf(stderr, "[sys-assert]read error\n"); - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - close(file); - return -1; - } - } - for (i = 0; i < elf_h.e_shnum; i++) { - if (s_headers[i].sh_type == SHT_SYMTAB) { - symtab_index = i; - if (s_headers[i].sh_entsize != 0 && - s_headers[i].sh_size != 0) { - num_st = - s_headers[i].sh_size / s_headers[i].sh_entsize; - found_symtab = 1; - } - break; - } - } - if (!found_symtab) { - fprintf(stderr, - "[sys-assert] can't find symtab\n"); - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - close(file); - } else { - /*.strtab index */ - if (symtab_index < elf_h.e_shnum) - strtab_index = s_headers[symtab_index].sh_link; - if (!strtab_index || elf_h.e_shnum <= strtab_index) { - fprintf_fd(fd, "%2d: (%p) [%s] + %p\n", - cnt, array[cnt], info_funcs.dli_fname, offset_addr); - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - close(file); - continue; - } - symtab_entry = - (Elf32_Sym *)mmap(0, sizeof(Elf32_Sym) * num_st, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (symtab_entry == NULL) { - fprintf(stderr, "[sys-assert]malloc failed\n"); - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - close(file); - return -1; - } - ret = lseek(file, s_headers[symtab_index].sh_offset, SEEK_SET); - if (ret < 0) { - fprintf_fd(fd, "%2d: (%p) [%s] + %p\n", - cnt, array[cnt], info_funcs.dli_fname, offset_addr); - munmap(symtab_entry, sizeof(Elf32_Sym) * num_st); - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - close(file); - continue; - } - for (i = 0; i < num_st; i++) { - ret = read(file, &symtab_entry[i], sizeof(Elf32_Sym)); - if (ret < sizeof(Elf32_Sym)) { - fprintf_fd(fd, - "[sys-assert]symtab_entry[%d], num_st=%d, readnum = %d\n", - i, num_st, ret); - break; - } - if (((info_funcs.dli_fbase + - symtab_entry[i].st_value) - <= array[cnt]) - && (array[cnt] <= - (info_funcs.dli_fbase + - symtab_entry[i].st_value + - symtab_entry[i].st_size))) { - if (symtab_entry[i].st_shndx != STN_UNDEF) { - ret = lseek(file, - s_headers[strtab_index].sh_offset + - symtab_entry[i].st_name, - SEEK_SET); - if (ret < 0) - break; - info_funcs.dli_sname = - (void *)mmap(0, FUNC_NAME_MAX_LEN, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - is_mapped = 1; - ret = read(file, (void *)info_funcs.dli_sname, - FUNC_NAME_MAX_LEN); - if (ret < 0) - break; - info_funcs.dli_saddr = - info_funcs.dli_fbase + - symtab_entry[i].st_value; - } - break; - } - } - munmap(s_headers, elf_h.e_shnum * sizeof(Elf32_Shdr)); - munmap(symtab_entry, sizeof(Elf32_Sym) * num_st); - close(file); - } - } - /* print symbol name and address. */ - if (info_funcs.dli_sname != NULL) { - if (array[cnt] >= info_funcs.dli_saddr) - fprintf_fd(fd, "%2d: %s + 0x%x (%p) [%s] + %p\n", - cnt, info_funcs.dli_sname, - (array[cnt] - info_funcs.dli_saddr), - array[cnt], info_funcs.dli_fname, offset_addr); - else - fprintf_fd(fd, "%2d: %s - 0x%x (%p) [%s] + %p\n", - cnt, info_funcs.dli_sname, - (info_funcs.dli_saddr - array[cnt]), - array[cnt], info_funcs.dli_fname, offset_addr); - if (is_mapped) - munmap((void *)info_funcs.dli_sname, FUNC_NAME_MAX_LEN); - } else { - fprintf_fd(fd, "%2d: (%p) [%s] + %p\n", - cnt, array[cnt], info_funcs.dli_fname, offset_addr); - } - } - return 0; -} -/* get address list from maps */ -static struct addr_node *get_addr_list_from_maps(int fd) -{ - int fpath_len, result; - long *saddr; - long *eaddr; - char perm[PERM_LEN]; - char path[PATH_MAX + 1]; - char addr[ADDR_BUF_LEN]; - char linebuf[BUF_SIZE]; - struct addr_node *head = NULL; - struct addr_node *tail = NULL; - struct addr_node *t_node = NULL; - - /* parsing the maps to get executable code address */ - while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) { - memset(path, 0, PATH_MAX + 1); - result = sscanf(linebuf, STR_FS(ADDR_BUF_LEN_DEC) - STR_FS(PERM_LEN_DEC) - "%*s %*s %*s" - STR_FS(PATH_MAX), addr, perm, path); - if (result < 0) - continue; - perm[PERM_LEN - 1] = 0; - /* rwxp */ -#ifdef ARCH_ARM - if ((perm[2] == 'x' && path[0] == '/') || - (perm[1] == 'w' && path[0] != '/')) { -#else - if (strncmp(perm, "r-xp", strlen("r-xp")) == 0) { -#endif - /* add addr node to list */ - addr[ADDR_LEN] = 0; - saddr = (long *)strtoul(addr, NULL, HEXA); - /* ffff0000-ffff1000 */ - eaddr = (long *)strtoul(&addr[ADDR_LEN + 1], NULL, HEXA); - /* make node and attach to the list */ - t_node = (struct addr_node *)mmap(0, sizeof(struct addr_node), - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (t_node == NULL) { - fprintf(stderr, "error : mmap\n"); - return NULL; - } - memcpy(t_node->perm, perm, PERM_LEN); - t_node->startaddr = saddr; - t_node->endaddr = eaddr; - t_node->fpath = NULL; - fpath_len = strlen(path); - if (fpath_len > 0) { - t_node->fpath = (char *)mmap(0, fpath_len + 1, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - memset(t_node->fpath, 0, fpath_len + 1); - memcpy(t_node->fpath, path, fpath_len); - } else { - t_node->fpath = (char *)mmap(0, STR_ANNOY_LEN, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - memset(t_node->fpath, 0, STR_ANNOY_LEN); - memcpy(t_node->fpath, STR_ANONY, STR_ANNOY_LEN); - } - t_node->next = NULL; - if (head == NULL) { - head = t_node; - tail = t_node; - } else { - tail->next = t_node; - tail = t_node; - } - } - } - return head; -} - -static void print_node_to_file(struct addr_node *start, int fd) -{ - struct addr_node *t_node; - - t_node = start; - fprintf_fd(fd, "\n%s\n", CRASH_MAPSINFO_TITLE); - while (t_node) { - if (!strncmp(STR_ANONY, t_node->fpath, STR_ANNOY_LEN)) { - t_node = t_node->next; - } else { - fprintf_fd(fd, - "%16lx %16lx %s %s\n", - (unsigned long)t_node->startaddr, - (unsigned long)t_node->endaddr, - t_node->perm, t_node->fpath); - t_node = t_node->next; - } - } - fprintf_fd(fd, "%s\n", CRASH_MAPSINFO_TITLE_E); -} - -static void free_all_nodes(struct addr_node *start) -{ - struct addr_node *t_node, *n_node; - int fpath_len; - - if (start == NULL) - return; - t_node = start; - n_node = t_node->next; - while (t_node) { - if (t_node->fpath != NULL) { - fpath_len = strlen(t_node->fpath); - munmap(t_node->fpath, fpath_len + 1); - } - munmap(t_node, sizeof(struct addr_node)); - if (n_node == NULL) - break; - t_node = n_node; - n_node = n_node->next; - } -} - -static void print_signal_info(int signum, const siginfo_t *info, int fd) -{ - fprintf_fd(fd, "Signal: %d\n", signum); - switch (signum) { - case SIGILL: - fprintf_fd(fd, " (SIGILL)\n"); - break; - case SIGTRAP: - fprintf_fd(fd, " (SIGTRAP)\n"); - break; - case SIGABRT: - fprintf_fd(fd, " (SIGABRT)\n"); - break; - case SIGBUS: - fprintf_fd(fd, " (SIGBUS)\n"); - break; - case SIGFPE: - fprintf_fd(fd, " (SIGFPE)\n"); - break; - case SIGSEGV: - fprintf_fd(fd, " (SIGSEGV)\n"); - break; - case SIGTERM: - fprintf_fd(fd, " (SIGTERM)\n"); - break; - case SIGSTKFLT: - fprintf_fd(fd, " (SIGSTKFLT)\n"); - break; - case SIGXCPU: - fprintf_fd(fd, " (SIGXCPU)\n"); - break; - case SIGXFSZ: - fprintf_fd(fd, " (SIGXFSZ)\n"); - break; - case SIGSYS: - fprintf_fd(fd, " (SIGSYS)\n"); - break; - default: - fprintf_fd(fd, "\n"); - } - /* print signal si_code info */ - fprintf_fd(fd, " si_code: %d\n", info->si_code); - if (info->si_code <= 0 || info->si_code >= 0x80) { - switch (info->si_code) { -#ifdef SI_TKILL - case SI_TKILL: - fprintf_fd(fd, - " signal sent by tkill (sent by pid %d, uid %d)\n", - info->si_pid, info->si_uid); - break; -#endif -#ifdef SI_USER - case SI_USER: - fprintf_fd(fd, - " signal sent by kill (sent by pid %d, uid %d)\n", - info->si_pid, info->si_uid); - break; -#endif -#ifdef SI_KERNEL - case SI_KERNEL: - fprintf_fd(fd, " signal sent by the kernel\n"); - break; -#endif - } - } else if (signum == SIGILL) { - switch (info->si_code) { - case ILL_ILLOPC: - fprintf_fd(fd, " illegal opcode\n"); - break; - case ILL_ILLOPN: - fprintf_fd(fd, " illegal operand\n"); - break; - case ILL_ILLADR: - fprintf_fd(fd, " illegal addressing mode\n"); - break; - case ILL_ILLTRP: - fprintf_fd(fd, " illegal trap\n"); - break; - case ILL_PRVOPC: - fprintf_fd(fd, " privileged opcode\n"); - break; - case ILL_PRVREG: - fprintf_fd(fd, " privileged register\n"); - break; - case ILL_COPROC: - fprintf_fd(fd, " coprocessor error\n"); - break; - case ILL_BADSTK: - fprintf_fd(fd, " internal stack error\n"); - break; - default: - fprintf_fd(fd, " illegal si_code = %d\n", info->si_code); - break; - } - fprintf_fd(fd, " si_addr: %p\n", info->si_addr); - } else if (signum == SIGFPE) { - switch (info->si_code) { - case FPE_INTDIV: - fprintf_fd(fd, " integer divide by zero\n"); - break; - case FPE_INTOVF: - fprintf_fd(fd, " integer overflow\n"); - break; - case FPE_FLTDIV: - fprintf_fd(fd, " floating-point divide by zero\n"); - break; - case FPE_FLTOVF: - fprintf_fd(fd, " floating-point overflow\n"); - break; - case FPE_FLTUND: - fprintf_fd(fd, " floating-point underflow\n"); - break; - case FPE_FLTRES: - fprintf_fd(fd, " floating-point inexact result\n"); - break; - case FPE_FLTINV: - fprintf_fd(fd, " invalid floating-point operation\n"); - break; - case FPE_FLTSUB: - fprintf_fd(fd, " subscript out of range\n"); - break; - default: - fprintf_fd(fd, " illegal si_code: %d\n", info->si_code); - break; - } - } else if (signum == SIGSEGV) { - switch (info->si_code) { - case SEGV_MAPERR: - fprintf_fd(fd, " address not mapped to object\n"); - break; - case SEGV_ACCERR: - fprintf_fd(fd, - " invalid permissions for mapped object\n"); - break; - default: - fprintf_fd(fd, " illegal si_code: %d\n", info->si_code); - break; - } - fprintf_fd(fd, " si_addr = %p\n", info->si_addr); - } else if (signum == SIGBUS) { - switch (info->si_code) { - case BUS_ADRALN: - fprintf_fd(fd, " invalid address alignment\n"); - break; - case BUS_ADRERR: - fprintf_fd(fd, " nonexistent physical address\n"); - break; - case BUS_OBJERR: - fprintf_fd(fd, " object-specific hardware error\n"); - break; - default: - fprintf_fd(fd, " illegal si_code: %d\n", info->si_code); - break; - } - fprintf_fd(fd, " si_addr: %p\n", info->si_addr); - } -} - -void sighandler(int signum, siginfo_t *info, void *context) -{ - int idx; - int readnum; - int threadnum; - /* file descriptor */ - int fd; - int fd_cs; /* for cs file */ - pid_t pid; - pid_t tid; - DIR *dir; - struct dirent *dentry = NULL; - char timestr[TIME_MAX_LEN]; - char processname[NAME_MAX] = {0,}; - char exepath[PATH_LEN] = {0,}; - char filepath[PATH_LEN]; - char crashid[TIME_MAX_LEN] = {0,}; - /* for get time */ - time_t cur_time; - /* for get info */ - char infoname[INFO_LEN]; - char value[VALUE_LEN]; - char linebuf[BUF_SIZE]; - char *p_exepath = NULL; - void *callstack_addrs[CALLSTACK_SIZE]; - int cnt_callstack = 0; - /* for backtrace_symbols() */ - struct addr_node *head = NULL; - /* for preventing recursion */ - static int retry_count = 0; - struct sysinfo si = {0,}; - - if (retry_count > 1) { - fprintf(stderr, "[sys-assert] recurcive called\n"); - return; - } - - cur_time = time(NULL); - /* get pid */ - pid = getpid(); - tid = (long int)syscall(__NR_gettid); - /* open maps file */ - if ((fd = open(MAPS_PATH, O_RDONLY)) < 0) { - fprintf(stderr, "[sys-assert]can't open %s\n", MAPS_PATH); - } else { - /* parsing the maps to get code segment address*/ - head = get_addr_list_from_maps(fd); - close(fd); - } - if (retry_count) - fprintf(stderr, "retry backtrace in sighandler"); - cnt_callstack = dump_callstack(callstack_addrs, CALLSTACK_SIZE, context, retry_count); - retry_count += 1; - /* get exepath */ - if ((readnum = open_read(CMDLINE_PATH, exepath, sizeof(exepath) - 1)) <= 0) { - fprintf(stderr, "[sys-assert]can't read %s\n", CMDLINE_PATH); - readnum = snprintf(exepath, sizeof(exepath), "unknown_process"); - } - exepath[readnum] = '\0'; - /* get processname */ - if ((p_exepath = remove_path(exepath)) == NULL) - return; - snprintf(processname, NAME_MAX, "%s", p_exepath); - /* added temporary skip when crash-worker is asserted */ - if (!strcmp(processname, "crash-worker") || - !strcmp(processname, "crash-popup")) - return; - /* make crash info file name */ - snprintf(timestr, sizeof(timestr), "%.10ld", cur_time); - snprintf(crashid, sizeof(crashid), "%s_%d", processname, pid); - if (snprintf(filepath, PATH_LEN, - "%s/%s.info", CRASH_INFO_PATH, crashid) == 0) { - fprintf(stderr, - "[sys-assert]can't make crash info file name : %s\n", - crashid); - return; - } - /* check crash info dump directory, make directory if absent */ - if (access(CRASH_INFO_PATH, F_OK) == -1) { - fprintf(stderr, "[sys-assert] No directory (%s)", CRASH_INFO_PATH); - /*TODO: making directory */ - return; - } - /* logging crash information to stderr */ - fprintf(stderr, "crashed [%s] processname=%s, pid=%d, tid=%d, signal=%d", - timestr, processname, pid, tid, signum); - /* complete filepath_cs */ - if (!strlen(filepath)) - return; - /* create cs file */ - if ((fd_cs = creat(filepath, FILE_PERMS)) < 0) { - fprintf(stderr, - "[sys-assert]can't create %s. errno = %d\n", - filepath, errno); - return; - } - - /* print exepath info */ - fprintf_fd(fd_cs, "Executable File Path: %s\n", exepath); - - /* print signal info */ - print_signal_info(signum, info, fd_cs); - fsync(fd_cs); - /* print register info */ - dump_registers(fd_cs, context); - - /* print meminfo */ - fprintf_fd(fd_cs, "\n%s\n", CRASH_MEMINFO_TITLE); - if (!sysinfo(&si)) { - fprintf_fd(fd_cs, "MemTotal: %8ld KB\n", KB(si.totalram)); - fprintf_fd(fd_cs, "MemFree: %8ld KB\n", KB(si.freeram)); - fprintf_fd(fd_cs, "Buffers: %8ld KB\n", KB(si.bufferram)); - } else - fprintf(stderr, "[sys-assert]can't get sysinfo\n"); - - if ((fd = open(MEMINFO_PATH, O_RDONLY)) < 0) { - fprintf(stderr, "[sys-assert]can't open %s\n", MEMINFO_PATH); - } else { - while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) { - sscanf(linebuf, STR_FS(INFO_LEN_DEC) - STR_FS(VALUE_LEN_DEC) - "%*s", infoname, value); - if (strcmp("Cached:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", infoname, value); - break; - } - } - close(fd); - } - - threadnum = 0; - if ((fd = open(STATUS_PATH, O_RDONLY)) < 0) { - fprintf(stderr, "[sys-assert]can't open %s\n", STATUS_PATH); - } else { - while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) { - sscanf(linebuf, STR_FS(INFO_LEN_DEC) - STR_FS(VALUE_LEN_DEC) - "%*s", infoname, value); - if (strcmp("VmPeak:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", infoname, - value); - } else if (strcmp("VmSize:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", infoname, - value); - } else if (strcmp("VmLck:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", infoname, - value); - } else if (strcmp("VmPin:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", infoname, - value); - } else if (strcmp("VmHWM:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmRSS:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmData:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmStk:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmExe:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmLib:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmPTE:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("VmSwap:", infoname) == 0) { - fprintf_fd(fd_cs, "%s %8s KB\n", - infoname, value); - } else if (strcmp("Threads:", infoname) == 0) { - threadnum = atoi(value); - break; - } - } - close(fd); - } - /* print thread info */ - if (1 < threadnum) { - fprintf_fd(fd_cs, "\n%s\n", CRASH_THREADINFO_TITLE); - fprintf_fd(fd_cs, - "Threads: %d\nPID = %d TID = %d\n", - threadnum, pid, tid); - /* print thread */ - dir = opendir(TASK_PATH); - if (!dir) { - fprintf(stderr, "[sys-assert]can't open %s\n", TASK_PATH); - } else { - while ((dentry = readdir(dir))) { - if (strcmp(dentry->d_name, ".") == 0 - || strcmp(dentry->d_name, "..") == 0) - continue; - fprintf_fd(fd_cs, "%s ", dentry->d_name); - } - closedir(dir); - fprintf_fd(fd_cs, "\n"); - } - } - if (head != NULL) { - /* print maps information */ - print_node_to_file(head, fd_cs); - /* print callstack */ - fprintf_fd(fd_cs, "\n%s (PID:%d)\n", CRASH_CALLSTACKINFO_TITLE, pid); - fprintf_fd(fd_cs, "Call Stack Count: %d\n", cnt_callstack); - if (trace_symbols(&callstack_addrs[CALLSTACK_BASE], - cnt_callstack, head, fd_cs) < 0) - fprintf(stderr, "[sys-assert] trace_symbols failed\n"); - fprintf_fd(fd_cs, "%s\n", CRASH_CALLSTACKINFO_TITLE_E); - free_all_nodes(head); - } - /* cs file sync */ - fsync(fd_cs); - /* clean up */ - if (close(fd_cs) == -1) - fprintf(stderr, "[sys-assert] fd_cs close error!!\n"); - /* core dump set */ - if (prctl(PR_GET_DUMPABLE) == 0) - prctl(PR_SET_DUMPABLE, 1); - - for (idx = 0; idx < NUM_SIG_TO_HANDLE; idx++) { - if (sig_to_handle[idx] == signum) { - sigaction(signum, &g_oldact[idx], NULL); - break; - } - } - raise(signum); -} - -__attribute__ ((constructor)) -void init() -{ - int idx; - - for (idx = 0; idx < NUM_SIG_TO_HANDLE; idx++) { - struct sigaction act; - act.sa_sigaction = (void *)sighandler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - act.sa_flags |= SA_RESETHAND; - if (sigaction(sig_to_handle[idx], &act, &g_oldact[idx]) < 0) { - perror("[sys-assert]could not set signal handler "); - continue; - } - } -} diff --git a/src/sys-assert/sys-assert.conf.in b/src/sys-assert/sys-assert.conf.in deleted file mode 100644 index 29dff1d..0000000 --- a/src/sys-assert/sys-assert.conf.in +++ /dev/null @@ -1,2 +0,0 @@ -d /tmp/crash_stack 1777 root root -t /tmp/crash_stack - - - - security.SMACK64=* diff --git a/src/sys-assert/sys-assert.h b/src/sys-assert/sys-assert.h deleted file mode 100755 index f24feac..0000000 --- a/src/sys-assert/sys-assert.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef _DEBUG_ASSERT_H_ -#define _DEBUG_ASSERT_H_ - -#include - -#ifdef ARCH_ARM -#define BASE_LAUNCHPAD_ADDR 0x8000 -#else -#define BASE_LAUNCHPAD_ADDR 0x8048000 -#endif -#define CALLSTACK_BASE 3 - -#ifdef __cplusplus -extern "C" { -#endif - - struct addr_node { - long *startaddr; - long *endaddr; - char perm[5]; - char *fpath; - struct addr_node *next; - }; - -#ifdef ARCH_ARM - typedef struct layout { - struct layout *fp; - void *ret; - } layout; - -#else - typedef struct layout { - struct layout *ebp; - void *ret; - } layout; -#endif - - extern void *__libc_stack_end; - -#ifdef __cplusplus -} -#endif -#endif /* _DEBUG_ASSERT_H_ */ diff --git a/src/sys-assert/util.c b/src/sys-assert/util.c deleted file mode 100644 index 3fc2e66..0000000 --- a/src/sys-assert/util.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include "util.h" - -int open_read(const char *path, char *buf, int size) -{ - int fd; - int ret; - - if (buf == NULL || path == NULL) - return -1; - - fd = open(path, O_RDONLY); - if (fd < 0) - return -1; - - ret = read(fd, buf, size - 1); - if (ret <= 0) { - close(fd); - return -1; - } else - buf[ret] = '\0'; - - close(fd); - - return ret; -} - -char *fgets_fd(char *str, int len, int fd) -{ - char ch; - register char *cs; - int num = 0; - - cs = str; - while (--len > 0 && (num = read(fd, &ch, 1) > 0)) { - if ((*cs++ = ch) == '\n') - break; - } - *cs = '\0'; - return (num == 0 && cs == str) ? NULL : str; -} - -char *remove_path(const char *cmd) -{ - char *cp; - char *np; - - cp = np = (char *)cmd; - while (*cp && *cp != ' ') { - if (*cp == '/') - np = cp + 1; - cp++; - } - return np; -} - -char *get_fpath(long *value, struct addr_node *start) -{ - struct addr_node *t_node; - struct addr_node *n_node; - - if (value == 0 || start == NULL) - return NULL; - t_node = start; - n_node = t_node->next; - while (n_node) { - if (t_node->endaddr <= value) { - t_node = n_node; - n_node = n_node->next; - } else if (t_node->startaddr <= value) { - return t_node->fpath; - } else - break; - } - return NULL; -} - -long *get_start_addr(long *value, struct addr_node *start) -{ - struct addr_node *t_node; - struct addr_node *n_node; - - if (value == 0 || start == NULL) - return NULL; - t_node = start; - n_node = t_node->next; - while (n_node) { - if (t_node->endaddr <= value) { - t_node = n_node; - n_node = n_node->next; - } else if (t_node->startaddr <= value) { - return t_node->startaddr; - } else - break; - } - return NULL; -} diff --git a/src/sys-assert/util.h b/src/sys-assert/util.h deleted file mode 100644 index ff7f7f3..0000000 --- a/src/sys-assert/util.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sys-assert.h" - -int open_read(const char *path, char *buf, int size); - -char *fgets_fd(char *str, int len, int fd); - -#define fprintf_fd(fd, fmt, ...) dprintf(fd, fmt, ##__VA_ARGS__) - -char *remove_path(const char *cmd); - -char *get_fpath(long *value, struct addr_node *start); - -long *get_start_addr(long *value, struct addr_node *start); diff --git a/src/sys-assert/x86/backtrace.c b/src/sys-assert/x86/backtrace.c deleted file mode 100644 index 4c07d86..0000000 --- a/src/sys-assert/x86/backtrace.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include "sys-assert.h" -#include "util.h" -#include "sys-assert-regs.h" - -int dump_callstack(void **callstack_addrs, int size, void *context, int retry) -{ - ucontext_t *ucontext = context; - int count = CALLSTACK_BASE; - - if (!callstack_addrs) - return 0; - - if (context) { - layout *ebp = (layout *)ucontext->uc_mcontext.gregs[REG_EBP]; - callstack_addrs[count++] = - (long *)ucontext->uc_mcontext.gregs[REG_EIP]; - while (ebp && (count < size)) { - callstack_addrs[count++] = ebp->ret; - ebp = ebp->ebp; - } - } else { - count = backtrace(callstack_addrs, size); - } - - if (count > CALLSTACK_BASE) { - count -= CALLSTACK_BASE; - } else if (context) { - callstack_addrs[CALLSTACK_BASE] = (long *)ucontext->uc_mcontext.gregs[REG_EIP]; - callstack_addrs[CALLSTACK_BASE + 1] = (long *)ucontext->uc_mcontext.gregs[REG_ESP]; - count = 2; - } else { - count = 0; - } - return count; -}; diff --git a/src/sys-assert/x86/context.c b/src/sys-assert/x86/context.c deleted file mode 100644 index 313ad86..0000000 --- a/src/sys-assert/x86/context.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SYS-ASSERT - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "sys-assert.h" -#include "util.h" -#include "sys-assert-regs.h" - -#define CRASH_REGISTERINFO_TITLE "Register Information" - -void dump_registers(int fd, void *context) -{ - ucontext_t *ucontext = context; - /* for context info */ - if (!context) - return; - - fprintf_fd(fd, "\n%s\n", CRASH_REGISTERINFO_TITLE); - fprintf_fd(fd, - "gs = 0x%08x, fs = 0x%08x\nes = 0x%08x, ds = 0x%08x\n", - ucontext->uc_mcontext.gregs[REG_GS], - ucontext->uc_mcontext.gregs[REG_FS], - ucontext->uc_mcontext.gregs[REG_ES], - ucontext->uc_mcontext.gregs[REG_DS]); - fprintf_fd(fd, - "edi = 0x%08x, esi = 0x%08x\nebp = 0x%08x, esp = 0x%08x\n", - ucontext->uc_mcontext.gregs[REG_EDI], - ucontext->uc_mcontext.gregs[REG_ESI], - ucontext->uc_mcontext.gregs[REG_EBP], - ucontext->uc_mcontext.gregs[REG_ESP]); - fprintf_fd(fd, - "eax = 0x%08x, ebx = 0x%08x\necx = 0x%08x, edx = 0x%08x\n", - ucontext->uc_mcontext.gregs[REG_EAX], - ucontext->uc_mcontext.gregs[REG_EBX], - ucontext->uc_mcontext.gregs[REG_ECX], - ucontext->uc_mcontext.gregs[REG_EDX]); - fprintf_fd(fd, - "eip = 0x%08x\n", - ucontext->uc_mcontext.gregs[REG_EIP]); -}; diff --git a/src/sys-assert/x86/sys-assert-regs.h b/src/sys-assert/x86/sys-assert-regs.h deleted file mode 100644 index f68baec..0000000 --- a/src/sys-assert/x86/sys-assert-regs.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SYS-ASSERT - * 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 __SYS_ASSERT_REGS_H__ -#define __SYS_ASSERT_REGS_H__ - -#include - -#ifndef REG_GS -#define REG_GS 0 -#endif - -#ifndef REG_FS -#define REG_FS 1 -#endif - -#ifndef REG_ES -#define REG_ES 2 -#endif - -#ifndef REG_DS -#define REG_DS 3 -#endif - -#ifndef REG_EDI -#define REG_EDI 4 -#endif - -#ifndef REG_ESI -#define REG_ESI 5 -#endif - -#ifndef REG_EBP -#define REG_EBP 6 -#endif - -#ifndef REG_ESP -#define REG_ESP 7 -#endif - -#ifndef REG_EBX -#define REG_EBX 8 -#endif - -#ifndef REG_EDX -#define REG_EDX 9 -#endif - -#ifndef REG_ECX -#define REG_ECX 10 -#endif - -#ifndef REG_EAX -#define REG_EAX 11 -#endif - -#ifndef REG_TRAPNO -#define REG_TRAPNO 12 -#endif - -#ifndef REG_ERR -#define REG_ERR 13 -#endif - -#ifndef REG_EIP -#define REG_EIP 14 -#endif - -#ifndef REG_CS -#define REG_CS 15 -#endif - -#ifndef REG_EFL -#define REG_EFL 16 -#endif - -#ifndef REG_UESP -#define REG_UESP 17 -#endif - -#ifndef REG_SS -#define REG_SS 18 -#endif - -#endif /* __SYS_ASSERT_REGS_H__ */ -- 2.7.4 From 82076809edf56498798d2a1190414fbe1bd6cfbc Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Mon, 30 Sep 2019 12:55:42 +0200 Subject: [PATCH 15/16] Pass the "-s" (without_core) parameter to the minicoredumper if dump_core is set to 0 Change-Id: I04be2a58f72d7dbb2dbfacd4d0c4b6e23c97dcf1 --- packaging/crash-worker.spec | 2 +- src/crash-manager/crash-manager.c | 5 ++++- src/shared/util.c | 16 +++++++++++++++- src/shared/util.h | 2 ++ tests/system/without_core/without_core.sh.template | 14 ++++++++++++++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index fc64bba..4d8fd96 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -47,7 +47,7 @@ Requires(post): gzip Requires: zip Requires: libelf Requires: libdw -Requires: %{_sbindir}/minicoredumper +Requires: minicoredumper >= 2.1.0 Requires: %{_bindir}/buxton2ctl %description diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index a96342e..86396db 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -571,6 +571,8 @@ static bool execute_minicoredump(struct crash_info *cinfo, int *exit_code) SNPRINTF_OR_EXIT(sig, "%d"); SNPRINTF_OR_EXIT(time, "%ld"); + const char *without_core_str = config.dump_core ? NULL : "-s"; + /* Execute minicoredumper */ char *args[] = { MINICOREDUMPER_BIN_PATH, // minicoredumper filename path @@ -588,6 +590,7 @@ static bool execute_minicoredump(struct crash_info *cinfo, int *exit_code) coredump_name, // coredump filename "-P", prstatus_fd_str, + (char *)without_core_str, // with or without core NULL }; @@ -596,7 +599,7 @@ static bool execute_minicoredump(struct crash_info *cinfo, int *exit_code) /* Minicoredumper must be executed to dump at least PRSTATUS for other tools, coredump, however, might have been disabled. */ - if (!config.dump_core) { + if (!config.dump_core && file_exists_in_dir(cinfo->pfx, coredump_name)) { if (remove_file_in_dir(cinfo->pfx, coredump_name) != 0) _E("Saving core disabled - removing coredump %s/%s failed: %m", cinfo->pfx, coredump_name); diff --git a/src/shared/util.c b/src/shared/util.c index d5917e7..6afc936 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -584,6 +584,21 @@ bool file_exists(const char *path) return stat(path, &buf) == 0; } +bool file_exists_in_dir(const char *base_dir, const char *file_name) +{ + char *path; + bool result = false; + + if (asprintf(&path, "%s/%s", base_dir, file_name) == -1) { + _E("Failed to asprintf for path: %m"); + } else { + result = file_exists(path); + free(path); + } + + return result; +} + bool write_to_file(const char *content, const char *base_dir, const char *file_name) { char *path; @@ -608,7 +623,6 @@ bool write_to_file(const char *content, const char *base_dir, const char *file_n } close(fd); - result = true; exit: free(path); return result; diff --git a/src/shared/util.h b/src/shared/util.h index 8e2a82f..f820997 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -70,6 +70,8 @@ bool string_ends_with(const char *string, const char *suffix); bool file_exists(const char *path); +bool file_exists_in_dir(const char *dir_path, const char *file_name); + bool write_to_file(const char *content, const char *base_dir, const char *file_name); #ifdef __cplusplus diff --git a/tests/system/without_core/without_core.sh.template b/tests/system/without_core/without_core.sh.template index ca13adf..d1371e1 100644 --- a/tests/system/without_core/without_core.sh.template +++ b/tests/system/without_core/without_core.sh.template @@ -39,4 +39,18 @@ if ls ${CRASH_DUMP_PATH}/kenny*/kenny*.coredump.tar > /dev/null; then fail "coredump file exists" fi +RESULT=$(cat ${CRASH_DUMP_PATH}/kenny*/kenny*info) +check "MemTotal:" +check "VmExe:" +check "VmSwap:" +check '[heap]' +check '/usr/lib/libm-.*.so' +check '/usr/lib/libc-.*.so' +check '/usr/lib/libgcc_s.so' +check '/usr/lib/libstdc++.*so' +check '/usr/lib/libpthread-.*.so' +check '/usr/lib/ld-.*.so' +check '[stack]' +check 'main.*kenny' + exit_ok -- 2.7.4 From 929ad348aa2e43becd68ce59a82d80b13a4ce36f Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Tue, 8 Oct 2019 12:13:14 +0200 Subject: [PATCH 16/16] Reduce heap usage When *.so_info was writing, for TPK packages, a complete list of packages and paths was built, to find a RPM package that contains the file. Now only the list of files is kept in memory, and then RPM database is iterated to find suitable package. Change-Id: I779661de26afd959945d441ba5ad160c99a014b2 --- src/crash-manager/so-info.c | 214 +++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 110 deletions(-) diff --git a/src/crash-manager/so-info.c b/src/crash-manager/so-info.c index bc1720b..b449791 100644 --- a/src/crash-manager/so-info.c +++ b/src/crash-manager/so-info.c @@ -37,6 +37,21 @@ #define BID_SNAME ".note.gnu.build-id" +struct rpm_info { + char *file_path; + char *app_name; + char *build_id; + char *rpm_info; +}; + +void rpm_info_free(struct rpm_info* ri) +{ + free(ri->file_path); + free(ri->app_name); + free(ri->build_id); + free(ri->rpm_info); + free(ri); +} static unsigned char *map_file(const char *filename, int64_t *size) { @@ -237,26 +252,26 @@ void free_rpm(rpmts ts) } } -char* get_rpm_info_as_string(Header h) +char* get_rpm_info_as_string_for_pkgname(Header h, const char *pkg_name) { - const char *name, *version, *release, *arch; + char *result = NULL; - name = headerGetString(h, RPMTAG_NAME); - version = headerGetString(h, RPMTAG_VERSION); - release = headerGetString(h, RPMTAG_RELEASE); - arch = headerGetString(h, RPMTAG_ARCH); + const char *version = headerGetString(h, RPMTAG_VERSION); + const char *release = headerGetString(h, RPMTAG_RELEASE); + const char *arch = headerGetString(h, RPMTAG_ARCH); - int info_len = strlen(name) + strlen(version) + - strlen(release) + strlen(arch) + 3; + if (version == NULL || release == NULL || arch == NULL) + _E("Failed to get version, release and arch for: %s", pkg_name); + else if (asprintf(&result, "%s;%s;%s;%s", pkg_name, version, release, arch) == -1) + _E("asprintf() error: %m"); - char *res = (char *)malloc(info_len + 1); - if (res == NULL) { - _E("Failed to allocate memory: %m"); - return NULL; - } - snprintf(res, info_len + 1, "%s;%s;%s;%s", name, version, release, arch); + return result; +} - return res; +char* get_rpm_info_as_string(Header h) +{ + const char *name = headerGetString(h, RPMTAG_NAME); + return get_rpm_info_as_string_for_pkgname(h, name); } char* get_rpm_info(rpmts ts, const char* filename) @@ -284,28 +299,23 @@ char* get_rpm_info(rpmts ts, const char* filename) return rpm_info; } -struct rpm_file { - char *pkg_name; - char *file_name; -}; - -GSList* create_tpk_list(rpmts ts) +void search_for_tpk(rpmts ts, GSList *pkgs) { - GSList *tpk_list = NULL; - rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMTAG_NAME, NULL, 0); if (mi == NULL) { _E("Failed to init rpmdb match iterator"); - goto end; + return; } - for (Header h = rpmdbNextIterator(mi); h; h = rpmdbNextIterator(mi)) { + guint count = g_slist_length(pkgs); // Initial number of packets with empty rpm_info + + for (Header h = rpmdbNextIterator(mi); count > 0 && h; h = rpmdbNextIterator(mi)) { const char *pkg_name = headerGetString(h, RPMTAG_NAME); if (pkg_name == NULL) continue; rpmfi fi = rpmfiNew(NULL, h, RPMTAG_FILENAMES, 0); - while (rpmfiNext(fi) != -1) { + while (count > 0 && rpmfiNext(fi) != -1) { const char *file_name = rpmfiFN(fi); size_t file_name_len = strlen(file_name); @@ -313,41 +323,28 @@ GSList* create_tpk_list(rpmts ts) strcmp(&file_name[file_name_len-4], ".tpk") != 0) continue; - const char *version = headerGetString(h, RPMTAG_VERSION); - const char *release = headerGetString(h, RPMTAG_RELEASE); - const char *arch = headerGetString(h, RPMTAG_ARCH); + for (GSList *iterator = pkgs; iterator; iterator = iterator->next) { + struct rpm_info *ri = (struct rpm_info *)iterator->data; + if (ri->rpm_info != NULL) + continue; - if (version == NULL || release == NULL || arch == NULL) - continue; + if (strstr(file_name, ri->app_name) == NULL) + continue; - struct rpm_file *rpm = (struct rpm_file*)malloc(sizeof(*rpm)); - if (rpm == NULL) { - _E("malloc() error (%m). Report (*.so_info) may be incomplete."); - continue; - } + char *info = get_rpm_info_as_string_for_pkgname(h, pkg_name); + if (info == NULL) + continue; - if (asprintf(&rpm->pkg_name, "%s;%s;%s;%s", - pkg_name, version, release, arch) == -1) { - _E("asprintf() error: %m"); - free(rpm); - continue; - } - rpm->file_name = strdup(file_name); - if (rpm->file_name == NULL) { - _E("strdup() error: %m"); - free(rpm->pkg_name); - free(rpm); - continue; + ri->rpm_info = info; + count--; + break; } - tpk_list = g_slist_append(tpk_list, rpm); } + + rpmfiFree(fi); } - rpmdbFreeIterator(mi); - if (tpk_list == NULL) - _E("No RPM packages containing *.tpk files found"); -end: - return tpk_list; + rpmdbFreeIterator(mi); } char* get_app_name_from_path(const char *file_path) @@ -368,85 +365,82 @@ char* get_app_name_from_path(const char *file_path) return NULL; } -char* get_rpm_info_for_tpk(GSList *tpk_list, const char *file_path) +void get_and_save_so_info(char *map_path, char *out_path) { - char *app_name = get_app_name_from_path(file_path); - if (app_name == NULL) - return NULL; - - char *res = NULL; - - for (GSList *iterator = tpk_list; iterator; iterator = iterator->next) { - struct rpm_file *rpm_pkg = (struct rpm_file *)iterator->data; - - if (strstr(rpm_pkg->file_name, app_name) != NULL) { - res = strdup(rpm_pkg->pkg_name); - break; - } + FILE *f = fopen(out_path, "w"); + if (f == NULL) { + _E("Failed to open file for writing %s: %m", out_path); + return; } - free(app_name); - return res; -} - -void get_and_save_so_info(char *map_path, char *out_path) -{ GSList *file_list = get_filepaths(map_path); - GSList *tpk_list = NULL; - - char *rpm_info; - FILE *f = fopen(out_path, "w"); + GSList *pkgs_not_found = NULL; rpmts ts = init_rpm(); - if (f == NULL) { - _E("Failed to open file for writing %s: %m", out_path); - } else { - char *build_id = NULL; - for (GSList *iterator = file_list; iterator; iterator = iterator->next) { - char *file_path = (char *)iterator->data; - - if (get_build_id(file_path, &build_id) <= 0 || build_id == NULL) - continue; + for (GSList *iterator = file_list; iterator; iterator = iterator->next) { + char *file_path = (char *)iterator->data; - int fret; + char *build_id = NULL; + if (get_build_id(file_path, &build_id) <= 0 || build_id == NULL) + continue; - rpm_info = get_rpm_info(ts, file_path); - if (rpm_info == NULL) { - if (tpk_list == NULL) - tpk_list = create_tpk_list(ts); - if (tpk_list != NULL) - rpm_info = get_rpm_info_for_tpk(tpk_list, file_path); + char *rpm_info = get_rpm_info(ts, file_path); + if (rpm_info == NULL) { + struct rpm_info *ri = malloc(sizeof(struct rpm_info)); + if (ri == NULL) { + _E("malloc error: %m"); + free(build_id); + break; } - if (rpm_info == NULL) - fret = fprintf(f, "%s %s\n", file_path, build_id); - else { - fret = fprintf(f, "%s %s %s\n", file_path, build_id, rpm_info); - free(rpm_info); + ri->file_path = strdup(file_path); + if (ri->file_path == NULL) { + _E("strdup error: %m"); + free(build_id); + free(ri); + break; } - + ri->app_name = get_app_name_from_path(file_path); + ri->build_id = build_id; + ri->rpm_info = NULL; + pkgs_not_found = g_slist_append(pkgs_not_found, ri); + } else { + int fret = fprintf(f, "%s %s %s\n", file_path, build_id, rpm_info); + free(rpm_info); free(build_id); if (fret < 0) { - _E("Failed to write to file %s", out_path); + _E("Failed to write to file %s: %m", out_path); break; } } - fclose(f); } - for (GSList *iterator = file_list; iterator; iterator = iterator->next) - free(iterator->data); + search_for_tpk(ts, pkgs_not_found); + + for (GSList *iterator = pkgs_not_found; iterator; iterator = iterator->next) { + struct rpm_info *ri = (struct rpm_info*)iterator->data; + int fret; + + if (ri->rpm_info == NULL) + fret = fprintf(f, "%s %s\n", ri->file_path, ri->build_id); + else + fret = fprintf(f, "%s %s %s\n", ri->file_path, ri->build_id, ri->rpm_info); + + if (fret < 0) + _E("Failed to write to file %s: %m", out_path); - for (GSList *iterator = tpk_list; iterator; iterator = iterator->next) { - struct rpm_file *rpm = (struct rpm_file*)iterator->data; - free(rpm->file_name); - free(rpm->pkg_name); - free(rpm); + rpm_info_free(ri); } + g_slist_free(pkgs_not_found); + + fclose(f); + + for (GSList *iterator = file_list; iterator; iterator = iterator->next) + free(iterator->data); + g_slist_free(file_list); - g_slist_free(tpk_list); free_rpm(ts); } -- 2.7.4