#undef GET_NUMBER
}
-static int set_crash_info(struct crash_info *cinfo)
+static bool set_crash_info(struct crash_info *cinfo)
{
int ret;
char *temp_dir_ret = NULL;
if (cinfo->livedump && !file_exists(LIVEDUMPER_BIN_PATH)) {
fprintf(stderr, "Error: %s doesn't exist - can not perform livedump. Terminating.\n", LIVEDUMPER_BIN_PATH);
_E("Error: %s doesn't exist - can not perform livedump. Terminating.\n", LIVEDUMPER_BIN_PATH);
- return -1;
+ return false;
}
if (cinfo->tid_info == -1) {
if (!get_cmd_info(cinfo)) {
_E("Failed to get command info");
- return -1;
+ return false;
}
if (cinfo->time_info == 0)
if (asprintf(&cinfo->temp_dir, "%s/crash.XXXXXX", crash_temp_path) == -1) {
_E("Failed to asprintf for temp_dir");
cinfo->temp_dir = NULL;
- return -1;
+ return false;
}
temp_dir_ret = mkdtemp(cinfo->temp_dir);
if (!temp_dir_ret || access(temp_dir_ret, F_OK)) {
_E("Failed to mkdtemp for temp_dir");
- return -1;
+ return false;
}
if (asprintf(&cinfo->name, "%s_%d_%s", basename(cinfo->cmd_line),
snprintf(cinfo->pkgid, sizeof(cinfo->pkgid), "%s", cinfo->appid);
}
- return 0;
+ return true;
rm_temp:
remove_dir(cinfo->temp_dir, 1);
- return -1;
+ return false;
}
#ifdef SYS_ASSERT
cinfo->time_info = 0;
}
-int main(int argc, char *argv[])
+static bool run(struct crash_info *cinfo)
{
- struct crash_info cinfo;
-
/* Execute processes in parallel */
static pid_t dump_state_pid = 0, extra_script_pid = 0;
int debug_mode = access(DEBUGMODE_PATH, F_OK) == 0;
- int res = 0;
-
- crash_info_init(&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.
- */
-
- if (!config_init(&config, CRASH_MANAGER_CONFIG_PATH)) {
- res = EXIT_FAILURE;
- goto exit;
- }
-
- if (!parse_args(&cinfo, argc, argv)) {
- res = EXIT_FAILURE;
- goto exit;
- }
-
- if (!prepare_paths(&cinfo)) {
- res = EXIT_FAILURE;
- goto exit;
- }
-
- if (!wait_for_opt(WAIT_FOR_OPT_TIMEOUT_SEC)) {
- res = EXIT_FAILURE;
- goto exit;
- }
-
- /* Create crash directories */
- if (!make_dump_dir()) {
- res = EXIT_FAILURE;
- goto exit;
- }
-
- /* Set crash info */
- if (set_crash_info(&cinfo) < 0) {
- res = EXIT_FAILURE;
- goto exit;
- }
#ifdef SYS_ASSERT
/* Fetch callstack of sys-assert */
- get_sysassert_cs(&cinfo);
+ get_sysassert_cs(cinfo);
#endif
if (config.report_type >= REP_TYPE_FULL) {
/* Exec dump_systemstate */
- if (!dump_system_state(&cinfo, &dump_state_pid)) {
- res = EXIT_FAILURE;
+ if (!dump_system_state(cinfo, &dump_state_pid)) {
_E("Failed to get system state report");
- goto exit;
+ return false;
}
- if (config.extra_script && !extra_script(&cinfo, &extra_script_pid))
+ if (config.extra_script && !extra_script(cinfo, &extra_script_pid))
_W("Failed to call extra script from config");
}
/* Exec crash modules */
- if (!execute_crash_modules(&cinfo)) {
- res = EXIT_FAILURE;
+ if (!execute_crash_modules(cinfo)) {
_E("Failed to get basic crash information");
- goto exit;
+ return false;
}
if (config.report_type >= REP_TYPE_FULL) {
/* Save shared objects info (file names, bulid IDs, rpm package names) */
- save_so_info(&cinfo);
+ save_so_info(cinfo);
/* Wait misc. pids */
wait_for_pid(dump_state_pid, NULL);
/* Tar compression */
if (config.allow_zip)
- compress(&cinfo);
+ compress(cinfo);
else
- move_dump_data(cinfo.pfx, &cinfo);
+ move_dump_data(cinfo->pfx, cinfo);
} else {
- free(cinfo.result_path);
- if (asprintf(&cinfo.result_path, "%s/%s.info",
- crash_dump_path, cinfo.name) == -1) {
- cinfo.result_path = NULL;
+ free(cinfo->result_path);
+ if (asprintf(&cinfo->result_path, "%s/%s.info",
+ crash_dump_path, cinfo->name) == -1) {
+ cinfo->result_path = NULL;
_E("asprintf() error: %m");
- res = EXIT_FAILURE;
- goto exit;
+ return false;
}
- move_dump_data(cinfo.info_path, &cinfo);
+ move_dump_data(cinfo->info_path, cinfo);
}
- if (cinfo.print_result_path)
- printf("REPORT_PATH=%s\n", cinfo.result_path);
+ if (cinfo->print_result_path)
+ printf("REPORT_PATH=%s\n", cinfo->result_path);
- if (!cinfo.livedump) {
+ if (!cinfo->livedump) {
/* Release the core pipe as passed by kernel, allowing another
* coredump to be handled.
*
*/
close(STDIN_FILENO);
- launch_dbus_notify(&cinfo);
+ launch_dbus_notify(cinfo);
/* launch crash-popup only if the .debugmode file exists */
if (debug_mode)
- launch_crash_popup(&cinfo);
- } else if (cinfo.kill) {
- kill_pid(cinfo.pid_info, SIGKILL, false);
+ launch_crash_popup(cinfo);
+ } else if (cinfo->kill) {
+ kill_pid(cinfo->pid_info, SIGKILL, false);
}
-exit:
- _I("Exiting with exit code %d", res);
- if (cinfo.prstatus_fd >= 0)
- close(cinfo.prstatus_fd);
+ return true;
+}
+
+bool crash_manager_prepare(struct crash_info *cinfo) {
+ if (!config_init(&config, CRASH_MANAGER_CONFIG_PATH))
+ return false;
+
+ if (!prepare_paths(cinfo))
+ return false;
+
+ if (!wait_for_opt(WAIT_FOR_OPT_TIMEOUT_SEC))
+ return false;
+
+ /* Create crash directories */
+ if (!make_dump_dir())
+ return false;
+
+ if (!set_crash_info(cinfo))
+ return false;
+
+ return true;
+}
+
+static void crash_manager_free(struct crash_info *cinfo)
+{
+ if (cinfo->prstatus_fd >= 0)
+ close(cinfo->prstatus_fd);
free(crash_temp_path);
free(crash_dump_path);
config_free(&config);
- free_crash_info(&cinfo);
+ free_crash_info(cinfo);
+}
+
+int main(int argc, char *argv[])
+{
+ 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 (!run(&cinfo))
+ res = EXIT_FAILURE;
+exit:
+ crash_manager_free(&cinfo);
+ _I("Exiting with exit code %d", res);
return res;
}