%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}
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
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)
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)
* limitations under the License.
*/
+#include <assert.h>
#include <dirent.h>
#include <fcntl.h>
#include <gio/gio.h>
#define LOG_TAG "CRASH_MANAGER"
#include "defs.h"
-#include "dbus_notify.h"
#include "shared/log.h"
#include "shared/config.h"
#include "shared/spawn.h"
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;
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.
*
*/
close(STDIN_FILENO);
+ launch_dbus_notify(&cinfo);
+
/* launch crash-popup only if the .debugmode file exists */
if (debug_mode)
launch_crash_popup(&cinfo);
/*
- * 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * Author: Mateusz Moscicki <m.moscicki2@partner.samsung.com>
+ * Authors: Mateusz Moscicki <m.moscicki2@partner.samsung.com>
+ * Karol Lewandowski <k.lewandowsk@samsung.com>
*/
+#define LOG_TAG "CRASH_MANAGER"
+#include "shared/log.h"
+#include "dbus-util.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <getopt.h>
#include <gio/gio.h>
+#include <stdbool.h>
#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/mman.h>
#include <sys/procfs.h>
-#include "shared/log.h"
-#include "dbus_notify.h"
+#include <unistd.h>
+
+#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
#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;
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,
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;
+}
+++ /dev/null
-/*
- *
- * 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 <m.moscicki2@partner.samsung.com>
- */
-
-#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);