From 27d75221855cdbb7c8b9446dff917a00b4dc6fac Mon Sep 17 00:00:00 2001 From: Konrad Kuchciak Date: Wed, 30 Oct 2019 11:06:53 +0100 Subject: [PATCH] Integrate with crash-service Crash report is now generated by calling crash-service via DBus instead of running crash-manager directly as a subprocess. Change-Id: I4b342314800d0943894b21298accf145ac902c26 --- Makefile | 2 +- config/default.conf | 5 ++ packaging/stability-monitor.spec | 7 +- src/action.c | 141 +++++++++++++------------------ 4 files changed, 69 insertions(+), 86 deletions(-) diff --git a/Makefile b/Makefile index cfaf793..8ffbd18 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ src = \ obj = $(src:.c=.o) -libs = json-c aul gio-2.0 glib-2.0 pkgmgr-info +libs = json-c aul gio-2.0 glib-2.0 pkgmgr-info crash-service CFLAGS = \ -Wall \ diff --git a/config/default.conf b/config/default.conf index 7201d71..195a9df 100644 --- a/config/default.conf +++ b/config/default.conf @@ -65,4 +65,9 @@ "monitor": 0, "apply_to_children": 1, }, + + "crash-service": { + "monitor": 0, + "apply_to_children": 1, + }, } diff --git a/packaging/stability-monitor.spec b/packaging/stability-monitor.spec index 1cdc1b7..858e553 100644 --- a/packaging/stability-monitor.spec +++ b/packaging/stability-monitor.spec @@ -1,7 +1,7 @@ %define KMOD_PATH %{_libdir}/stability-monitor/proc-tsm.ko Name: stability-monitor -Version: 5.5.1 +Version: 6.0.0 Release: 0 License: Apache-2.0 Source0: %{name}-%{version}.tar.xz @@ -13,10 +13,11 @@ BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(crash-worker-devel) ExclusiveArch: armv7l Requires: %{KMOD_PATH} -Requires: crash-worker >= 5.5.18 -Requires: crash-worker-livedumper >= 5.5.18 +Requires: crash-worker >= 5.5.22 +Requires: crash-worker-livedumper >= 5.5.22 %description This package provides stability monitoring daemon. diff --git a/src/action.c b/src/action.c index 5831074..4a220c6 100644 --- a/src/action.c +++ b/src/action.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "utils.h" #include "log.h" @@ -124,102 +125,69 @@ skip_dbus_signal: free(ad); } -static void crash_manager_exit_cb(GPid pid, gint status, gpointer user_data) +static void livedump_pid_thread_cb(GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) { - struct action_data *ad = user_data; - FILE *stream = NULL; - char *line = NULL; - size_t len = 0; - ssize_t n; - - if (!g_spawn_check_exit_status (status, NULL)) { - _E("Crash-manager failed with code: %d", status); - - stream = fdopen(ad->stderr_fd, "r"); - if (!stream) { - _E("Unable to open stderr stream: %m"); - goto finish; - } - - while ((n = getline(&line, &len, stream)) != -1) - _D("%s", line); - - goto finish; - } - - stream = fdopen(ad->stdout_fd, "r"); - if (!stream) { - _E("Unable to open stdout stream: %m"); + struct action_data *ad = task_data; + char reason[4096]; + int ret; + char *actual_str = g_variant_print(ad->actual_value, TRUE); + char *allowed_str = g_variant_print(ad->allowed_value, TRUE); + + ret = sprintf(reason, "Stability-monitor detected abnormality.\n" + "Process name: %s\n" + "PID: %d\n" + "Exceeded parameter: %s\n" + "Actual value: %s\n" + "Allowed value: %s\n", + ad->ds->process->name, + ad->ds->process->pid, + ad->ds->param_name, + actual_str, + allowed_str); + if (ret == -1) { + _E("Couldn't print dbus object path: %m"); goto finish; } - /* Get report path from stdout */ - while ((n = getline(&line, &len, stream)) != -1) { - if (strncmp(line, "REPORT_PATH=", 12) == 0) { - line[n-1] = 0; - - ad->report_path = strndup(line + 12, n - 12); - if (!ad->report_path) - _E("Unable to allocate memory"); - else - _D_PROC(ad->ds->process, "Received report: %s", ad->report_path); - - goto finish; - } - } - - _E("Crash-worker ended without error but didn't provide report path"); + ret = (livedump_pid(ad->ds->process->pid, reason, ad->report_path, PATH_MAX) == FALSE); finish: - action_finish(ad); // NB: also closes `stream` through `ad->stdout_fd` - - free(line); - g_spawn_close_pid(pid); + free(actual_str); + free(allowed_str); + g_task_return_int(task, ret); } -static GPid spawn_crash_manager(struct action_data *ad) +void livedump_pid_async(GAsyncReadyCallback callback, + gpointer user_data) { - GPid child_pid = 0; - GError *error = NULL; - char *pid_str = NULL; - if (asprintf(&pid_str, "%d", ad->ds->process->pid) == -1) - goto out; - - char *argv[] = {CRASH_MANAGER_BIN, "-lrp", pid_str, NULL}; - - _D_PROC(ad->ds->process, "Generating report..."); - - /* Spawn child */ - if (!g_spawn_async_with_pipes(NULL, argv, NULL, - G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, - NULL, &child_pid, NULL, &ad->stdout_fd, &ad->stderr_fd, &error)) { - - _E("Unable to spawn child process: %s", error->message); - g_error_free(error); - } - _D("Spawned child process pid %d", child_pid); + struct action_data *ad = user_data; + GTask *task = g_task_new(NULL, NULL, callback, user_data); -out: - free(pid_str); - return child_pid; + g_task_set_source_tag(task, livedump_pid_async); + g_task_set_task_data(task, ad, NULL); + g_task_run_in_thread(task, livedump_pid_thread_cb); + g_object_unref(task); } -static gboolean action_run(gpointer data) +static void on_livedump_complete(GObject *gobject, + GAsyncResult *result, + gpointer user_data) { - struct action_data *ad = data; - GPid child_pid; - - if (ad->ds->process->report) { - child_pid = spawn_crash_manager(ad); - if (child_pid != 0) { - g_child_watch_add(child_pid, crash_manager_exit_cb, ad); - return FALSE; - } + struct action_data *ad = user_data; + int ret; + + ret = g_task_propagate_int(G_TASK(result), NULL); + if (ret) { + _E("livedump_pid() failed (for more info please check 'dlogutil LIBCRASH-SERVICE' and/or 'dlogutil CRASH_MANAGER'"); + ad->report_path[0] = 0; + } else { + _D_PROC(ad->ds->process, "Received report: %s", ad->report_path); } action_finish(ad); - - return FALSE; } int action_run_default(struct data_source *ds, enum limit_type lt) @@ -239,8 +207,14 @@ int action_run_default(struct data_source *ds, enum limit_type lt) return -ENOMEM; } + ad->report_path = calloc(1, PATH_MAX); + if (!ad->report_path) { + _E("Unable to allocate memory"); + free(ad); + return -ENOMEM; + } + ad->ds = ds; - ad->report_path = NULL; ad->lt = lt; if (lt == LIMIT_TYPE_AVG) { @@ -252,7 +226,10 @@ int action_run_default(struct data_source *ds, enum limit_type lt) } process_ref(ds->process); - g_timeout_add(0, action_run, ad); + if (ad->ds->process->report) + livedump_pid_async(on_livedump_complete, ad); + else + action_finish(ad); return 0; } -- 2.34.1