From 0c19700680391201dab686381473537c95d2124e Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 25 Apr 2019 13:31:43 +0200 Subject: [PATCH] Split dbus-notify-send from crash-manager Change-Id: I12b9a6b513fba53335eee71bf10c5c2b83ca3349 --- packaging/crash-worker.spec | 1 + src/crash-manager/CMakeLists.txt | 16 +++- src/crash-manager/crash-manager.c | 50 ++++++++---- src/crash-manager/dbus_notify.c | 161 +++++++++++++++++++++++++++++--------- src/crash-manager/dbus_notify.h | 43 ---------- 5 files changed, 174 insertions(+), 97 deletions(-) delete mode 100644 src/crash-manager/dbus_notify.h diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 5b6cea8..efbb324 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -183,6 +183,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload %attr(0750,system_fw,system_fw) %{_bindir}/dump_systemstate %{_libexecdir}/crash-stack %{_libexecdir}/crash-popup-launch +%{_libexecdir}/crash-notify-send %if %{with logdump} %dir %{crash_all_log} diff --git a/src/crash-manager/CMakeLists.txt b/src/crash-manager/CMakeLists.txt index 01c2a97..6a20570 100644 --- a/src/crash-manager/CMakeLists.txt +++ b/src/crash-manager/CMakeLists.txt @@ -5,7 +5,6 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) SET(CRASH_MANAGER_SRCS crash-manager.c so-info.c - dbus_notify.c ${CMAKE_SOURCE_DIR}/src/shared/util.c ${CMAKE_SOURCE_DIR}/src/shared/spawn.c ${CMAKE_SOURCE_DIR}/src/shared/config.c @@ -16,12 +15,16 @@ pkg_check_modules(crash-manager_pkgs REQUIRED dlog libtzplatform-config iniparser - gio-2.0 pkgmgr-info rpm ) -FOREACH(flag ${crash-manager_pkgs_CFLAGS}) +pkg_check_modules(helper_pkgs REQUIRED + dlog + gio-2.0 + ) + +FOREACH(flag ${crash-manager_pkgs_CFLAGS} ${helper_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) @@ -32,9 +35,14 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie -lrt) set(CRASH_POPUP crash-popup-launch) ADD_EXECUTABLE(${CRASH_POPUP} ${CRASH_POPUP}.c) -TARGET_LINK_LIBRARIES(crash-popup-launch ${crash-manager_pkgs_LDFLAGS} -pie -lrt) +TARGET_LINK_LIBRARIES(${CRASH_POPUP} ${helper_pkgs_LDFLAGS}) install(TARGETS ${CRASH_POPUP} DESTINATION libexec) +SET(CRASH_NOTIFY crash-notify-send) +ADD_EXECUTABLE(${CRASH_NOTIFY} dbus_notify.c) +TARGET_LINK_LIBRARIES(${CRASH_NOTIFY} ${helper_pkgs_LDFLAGS}) +install(TARGETS ${CRASH_NOTIFY} DESTINATION libexec) + 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/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 10c3cd6..321dd4b 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -16,6 +16,7 @@ * limitations under the License. */ +#include #include #include #include @@ -42,7 +43,6 @@ #define LOG_TAG "CRASH_MANAGER" #include "defs.h" -#include "dbus_notify.h" #include "shared/log.h" #include "shared/config.h" #include "shared/spawn.h" @@ -510,10 +510,41 @@ end: return ret; } -// These macros are used in execute_minicoredump() and execute_crash_stack() +// 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(name, format) SNPRINTF_OR_EXIT_W(name, format, name##_info) +static void launch_dbus_notify(struct crash_info *cinfo) +{ + assert(cinfo); + + char pid_str[11], tid_str[11]; + char *prstatus_fd_str = NULL; + + if (asprintf(&prstatus_fd_str, "%d", cinfo->prstatus_fd) == -1) { + _E("Unable to allocate memory: %m"); + return; + } + + SNPRINTF_OR_EXIT(pid, "%d") + SNPRINTF_OR_EXIT(tid, "%d") + + char *av[] = { "/usr/libexec/crash-notify-send", + "--cmdline", cinfo->cmd_line, + "--cmdpath", cinfo->cmd_path, + "--pid", pid_str, + "--tid", tid_str, + "--appid", cinfo->appid, + "--pkgid", cinfo->pkgid, + "--reportpath", cinfo->result_path, + "--prstatus_fd", prstatus_fd_str, + NULL }; + + spawn(av, NULL, NULL, NULL, NULL, NULL); +out: + free(prstatus_fd_str); +} + static bool execute_minicoredump(struct crash_info *cinfo, int *exit_code) { char *coredump_name = NULL; @@ -1043,19 +1074,6 @@ int main(int argc, char *argv[]) move_dump_data(cinfo.info_path, &cinfo); } - struct NotifyParams notify_params = { - .prstatus_fd = cinfo.prstatus_fd, - .pid = cinfo.pid_info, - .tid = cinfo.tid_info, - .cmd_name = basename(cinfo.cmd_line), - .cmd_path = cinfo.cmd_path, - .report_path = cinfo.result_path, - .appid = cinfo.appid, - .pkgid = cinfo.pkgid - }; - - send_notify(¬ify_params); - /* Release the core pipe as passed by kernel, allowing another * coredump to be handled. * @@ -1069,6 +1087,8 @@ int main(int argc, char *argv[]) */ close(STDIN_FILENO); + launch_dbus_notify(&cinfo); + /* launch crash-popup only if the .debugmode file exists */ if (debug_mode) launch_crash_popup(&cinfo); diff --git a/src/crash-manager/dbus_notify.c b/src/crash-manager/dbus_notify.c index cf78f6a..32448a2 100644 --- a/src/crash-manager/dbus_notify.c +++ b/src/crash-manager/dbus_notify.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -13,19 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Author: Mateusz Moscicki + * Authors: Mateusz Moscicki + * Karol Lewandowski */ +#define LOG_TAG "CRASH_MANAGER" +#include "shared/log.h" +#include "dbus-util.h" + +#include +#include +#include #include +#include #include -#include -#include -#include #include +#include #include #include -#include "shared/log.h" -#include "dbus_notify.h" +#include + +#define CRASH_BUS_NAME "org.tizen.system.crash" +#define CRASH_OBJECT_PATH "/Org/Tizen/System/Crash" +#define CRASH_INTERFACE_NAME CRASH_BUS_NAME +#define CRASH_PATH_CRASH CRASH_OBJECT_PATH"/Crash" +#define CRASH_INTERFACE_CRASH CRASH_INTERFACE_NAME".Crash" +#define PROCESS_CRASHED "ProcessCrashed" #define KERNEL_DEFINED_TASK_COMM_LEN 16 // from include/linux/sched.h @@ -33,6 +46,22 @@ #define ARM_REG_PC 15 #define AARCH64_REG_LR 30 +struct RegInfo { + char *name; + long long int value; +}; + +struct NotifyParams { + int prstatus_fd; + pid_t pid; + pid_t tid; + char *cmd_name; + char *cmd_path; + char *report_path; + char *appid; + char *pkgid; +}; + static int _get_important_registers(int fd, struct RegInfo **reg_info) { int count = -1; @@ -160,29 +189,17 @@ static GVariant* build_message_data(const struct NotifyParams *notify_params) return g_variant_builder_end(&md_builder); } -int send_notify(const struct NotifyParams *notify_params) +static bool send_notify(GDBusConnection *conn, const struct NotifyParams *notify_params) { - int result = 1; - - GDBusConnection *conn = NULL; - GError *error = NULL; - - conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (error) { - _E("g_bus_get_sync error: %s\n", error->message); - g_error_free(error); - result = 0; - goto end; - } + int result = false; GVariant *data = build_message_data(notify_params); - if (data == NULL) { - _E("build_message error\n"); - result = 0; - goto end; + _E("Error while preparing parameters"); + goto out; } + GError *error = NULL; g_dbus_connection_emit_signal(conn, NULL, CRASH_PATH_CRASH, @@ -190,22 +207,96 @@ int send_notify(const struct NotifyParams *notify_params) PROCESS_CRASHED, data, &error); - if (error) { - _E("g_dbus_connection_emit_signal error: %s\n", error->message); - g_error_free(error); - result = 0; - goto end; + _E("Failed to emit signal: %s", error->message); + goto out; } g_dbus_connection_flush_sync(conn, NULL, &error); - if (error) { - _E("g_dbus_connection_flush_sync error: %s\n", error->message); + if (error) + _E("Failed to flush connection - signal might not be delivered: %s", error->message); + + result = true; + +out: + if (error) g_error_free(error); - } -end: - if (conn != NULL) - g_object_unref(conn); return result; } + +static bool parse_cmdline(int ac, char *av[], struct NotifyParams *params) +{ + assert(av); + assert(params); + + enum { + FLAG_CMDLINE = 1, + FLAG_CMDPATH, + FLAG_PID, + FLAG_TID, + FLAG_APPID, + FLAG_PKGID, + FLAG_REPORTPATH, + FLAG_PRSTATUS_FD, + }; + static const struct option options[] = { + { .name = "cmdline", .has_arg = required_argument, .flag = NULL, .val = FLAG_CMDLINE }, + { .name = "cmdpath", .has_arg = required_argument, .flag = NULL, .val = FLAG_CMDPATH }, + { .name = "pid", .has_arg = required_argument, .flag = NULL, .val = FLAG_PID }, + { .name = "tid", .has_arg = required_argument, .flag = NULL, .val = FLAG_TID }, + { .name = "appid", .has_arg = required_argument, .flag = NULL, .val = FLAG_APPID }, + { .name = "pkgid", .has_arg = required_argument, .flag = NULL, .val = FLAG_PKGID }, + { .name = "reportpath", .has_arg = required_argument, .flag = NULL, .val = FLAG_REPORTPATH }, + { .name = "prstatus_fd", .has_arg = required_argument, .flag = NULL, .val = FLAG_PRSTATUS_FD }, + { NULL }, + }; + + int val; + do { + val = getopt_long_only(ac, av, "", options, NULL); + + if (FLAG_CMDLINE == val) + params->cmd_name = basename(optarg); + else if (FLAG_CMDPATH == val) + params->cmd_path = optarg; + else if (FLAG_PID == val) + params->pid = atoi(optarg); + else if (FLAG_TID == val) + params->tid = atoi(optarg); + else if (FLAG_APPID == val) + params->appid = optarg; + else if (FLAG_PKGID == val) + params->pkgid = optarg; + else if (FLAG_PRSTATUS_FD == val) + params->prstatus_fd = atoi(optarg); + } while (val != -1); + + return params->cmd_name && params->cmd_path && params->appid && params->pkgid && params->prstatus_fd > 0; +} + +static void usage(const char *const progname) +{ + assert(progname); + + printf("%s --prstatus_fd N --pid PID --tid TID --cmdline CMDLINE --cmdpath CMDPATH --appid APPID --pkgid PKGID\n", progname); +} + +int main(int ac, char *av[]) +{ + struct NotifyParams params = {0, }; + + if (!parse_cmdline(ac, av, ¶ms)) { + usage(av[0]); + return EXIT_FAILURE; + } + + GDBusConnection *conn = NULL; + if (!bus_get(&conn)) + return EXIT_FAILURE; + + send_notify(conn, ¶ms); + bus_put(conn); + + return EXIT_SUCCESS; +} diff --git a/src/crash-manager/dbus_notify.h b/src/crash-manager/dbus_notify.h deleted file mode 100644 index 7c2f24d..0000000 --- a/src/crash-manager/dbus_notify.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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. - * - * Author: Mateusz Moscicki - */ - -#define CRASH_BUS_NAME "org.tizen.system.crash" -#define CRASH_OBJECT_PATH "/Org/Tizen/System/Crash" -#define CRASH_INTERFACE_NAME CRASH_BUS_NAME -#define CRASH_PATH_CRASH CRASH_OBJECT_PATH"/Crash" -#define CRASH_INTERFACE_CRASH CRASH_INTERFACE_NAME".Crash" -#define PROCESS_CRASHED "ProcessCrashed" - -struct RegInfo { - char *name; - long long int value; -}; - -struct NotifyParams { - int prstatus_fd; - pid_t pid; - pid_t tid; - char *cmd_name; - char *cmd_path; - char *report_path; - char *appid; - char *pkgid; -}; - -int send_notify(const struct NotifyParams *notify_params); -- 2.7.4