From 35ef82f3738efc9872f5b6f926d47256a7fe38b2 Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Fri, 31 Aug 2018 12:07:56 +0200 Subject: [PATCH] Stop using crash_info struct as a global variable Change-Id: I1dee72cb7abf29e7ff2bf5bdc4e0852bda1329b1 --- src/crash-manager/crash-manager.c | 256 +++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 127 deletions(-) diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 3603907..cf6525e 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -112,7 +112,7 @@ static char* crash_temp_path; static int report_type; /* Paths and variables */ -static struct crash_info { +struct crash_info { pid_t pid_info; pid_t tid_info; int uid_info; @@ -135,7 +135,7 @@ static struct crash_info { bool have_sysassert_report; #endif int prstatus_fd; -} crash_info; +}; /* pkgmgrinfo filter list function for getting application ID */ static int appinfo_get_appid_func(pkgmgrinfo_appinfo_h handle, @@ -434,19 +434,19 @@ static int get_cmd_info(struct crash_info *cinfo) get_exe_path(cinfo->pid_info, cinfo->cmd_path, sizeof(cinfo->cmd_path)); } -static int set_prstatus() +static int set_prstatus(struct crash_info *cinfo) { int ret; char prstatus_name[NAME_MAX+1]; - ret = snprintf(prstatus_name, NAME_MAX, "/%d.prstatus", crash_info.pid_info); + ret = snprintf(prstatus_name, NAME_MAX, "/%d.prstatus", cinfo->pid_info); if (ret < 0) { _E("Failed to snprintf for prstatus path"); goto close_fd; } - crash_info.prstatus_fd = shm_open(prstatus_name, O_RDWR | O_CREAT, 0600); - if (crash_info.prstatus_fd < 0) { + cinfo->prstatus_fd = shm_open(prstatus_name, O_RDWR | O_CREAT, 0600); + if (cinfo->prstatus_fd < 0) { _E("shm_open: %m"); goto close_fd; } @@ -457,19 +457,19 @@ static int set_prstatus() goto close_fd; } - ret = fcntl(crash_info.prstatus_fd, F_GETFD); + ret = fcntl(cinfo->prstatus_fd, F_GETFD); if (ret < 0) { _E("fcntl(): %m"); goto close_fd; } - ret = fcntl(crash_info.prstatus_fd, F_SETFD, ret & ~FD_CLOEXEC); + ret = fcntl(cinfo->prstatus_fd, F_SETFD, ret & ~FD_CLOEXEC); if (ret < 0) { _E("fcntl(): %m"); goto close_fd; } - ret = ftruncate(crash_info.prstatus_fd, sizeof(struct elf_prstatus)); + ret = ftruncate(cinfo->prstatus_fd, sizeof(struct elf_prstatus)); if (ret < 0) { _E("ftruncate(): %m"); goto close_fd; @@ -478,55 +478,55 @@ static int set_prstatus() return 0; close_fd: - if (crash_info.prstatus_fd >= 0) - close(crash_info.prstatus_fd); + if (cinfo->prstatus_fd >= 0) + close(cinfo->prstatus_fd); return -1; } -static int set_crash_info(int argc, char *argv[]) +static int set_crash_info(struct crash_info *cinfo, int argc, char *argv[]) { int ret; char *temp_dir_ret = NULL; char date[80]; struct tm loc_tm; - crash_info.pid_info = strtol(argv[1], NULL, 10); - crash_info.sig_info = atoi(argv[4]); + cinfo->pid_info = strtol(argv[1], NULL, 10); + cinfo->sig_info = atoi(argv[4]); if (argc > 6) - crash_info.tid_info = strtol(argv[6], NULL, 10); + cinfo->tid_info = strtol(argv[6], NULL, 10); else { - crash_info.tid_info = find_crash_tid(crash_info.pid_info); - if (crash_info.tid_info < 0) { + cinfo->tid_info = find_crash_tid(cinfo->pid_info); + if (cinfo->tid_info < 0) { _I("TID not found"); - crash_info.tid_info = crash_info.pid_info; + cinfo->tid_info = cinfo->pid_info; } } - ret = get_cmd_info(&crash_info); + ret = get_cmd_info(cinfo); if (ret <= 0) { _E("Failed to get command info"); return -1; } - crash_info.time_info = strtol(argv[5], NULL, 10); - localtime_r(&crash_info.time_info, &loc_tm); + cinfo->time_info = strtol(argv[5], NULL, 10); + localtime_r(&cinfo->time_info, &loc_tm); strftime(date, sizeof(date), "%Y%m%d%H%M%S", &loc_tm); - ret = snprintf(crash_info.temp_dir, sizeof(crash_info.temp_dir), + ret = snprintf(cinfo->temp_dir, sizeof(cinfo->temp_dir), "%s/crash.XXXXXX", crash_temp_path); if (ret < 0) { _E("Failed to snprintf for temp_dir"); return -1; } - temp_dir_ret = mkdtemp(crash_info.temp_dir); + 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; } - ret = snprintf(crash_info.name, sizeof(crash_info.name), "%s_%d_%s", - basename(crash_info.cmd_line), - crash_info.pid_info, + ret = snprintf(cinfo->name, sizeof(cinfo->name), "%s_%d_%s", + basename(cinfo->cmd_line), + cinfo->pid_info, date); if (ret < 0) { _E("Failed to snprintf for name"); @@ -534,103 +534,103 @@ static int set_crash_info(int argc, char *argv[]) } if (allow_zip) - ret = snprintf(crash_info.result_path, - sizeof(crash_info.result_path), - "%s/%s.zip", crash_crash_path, crash_info.name); + ret = snprintf(cinfo->result_path, + sizeof(cinfo->result_path), + "%s/%s.zip", crash_crash_path, cinfo->name); else - ret = snprintf(crash_info.result_path, - sizeof(crash_info.result_path), - "%s/%s", crash_crash_path, crash_info.name); + ret = snprintf(cinfo->result_path, + sizeof(cinfo->result_path), + "%s/%s", crash_crash_path, cinfo->name); if (ret < 0) { _E("Failed to snprintf for result path"); goto rm_temp; } - ret = snprintf(crash_info.pfx, sizeof(crash_info.pfx), "%s/%s", - crash_info.temp_dir, crash_info.name); + ret = snprintf(cinfo->pfx, sizeof(cinfo->pfx), "%s/%s", + cinfo->temp_dir, cinfo->name); if (ret < 0) { _E("Failed to snprintf for pfx"); goto rm_temp; } - ret = mkdir(crash_info.pfx, 0775); + ret = mkdir(cinfo->pfx, 0775); if (ret < 0) { - _E("Failed to mkdir for %s", crash_info.pfx); + _E("Failed to mkdir for %s", cinfo->pfx); goto rm_temp; } - ret = snprintf(crash_info.info_path, sizeof(crash_info.info_path), - "%s/%s.info", crash_info.pfx, crash_info.name); + ret = snprintf(cinfo->info_path, sizeof(cinfo->info_path), + "%s/%s.info", cinfo->pfx, cinfo->name); if (ret < 0) { _E("Failed to snprintf for info path"); goto rm_temp; } - ret = snprintf(crash_info.core_path, sizeof(crash_info.core_path), - "%s/%s.coredump", crash_info.pfx, crash_info.name); + ret = snprintf(cinfo->core_path, sizeof(cinfo->core_path), + "%s/%s.coredump", cinfo->pfx, cinfo->name); if (ret < 0) { _E("Failed to snprintf for core path"); goto rm_temp; } - ret = snprintf(crash_info.log_path, sizeof(crash_info.log_path), - "%s/%s.log", crash_info.pfx, crash_info.name); + ret = snprintf(cinfo->log_path, sizeof(cinfo->log_path), + "%s/%s.log", cinfo->pfx, cinfo->name); if (ret < 0) { _E("Failed to snprintf for log path"); goto rm_temp; } #ifdef SYS_ASSERT - ret = snprintf(crash_info.sysassert_cs_path, - sizeof(crash_info.sysassert_cs_path), + ret = snprintf(cinfo->sysassert_cs_path, + sizeof(cinfo->sysassert_cs_path), "/tmp/crash_stack/%s_%d.info", - basename(crash_info.cmd_line), crash_info.pid_info); + basename(cinfo->cmd_line), cinfo->pid_info); if (ret < 0) { _E("Failed to snprintf for sys-assert callstack path"); goto rm_temp; } #endif - if (set_prstatus() < 0) + if (set_prstatus(cinfo) < 0) goto rm_temp; - if (get_appid(crash_info.cmd_line, crash_info.appid, sizeof(crash_info.appid)) < 0) { - snprintf(crash_info.appid, sizeof(crash_info.appid), "%s", basename(crash_info.cmd_line)); - snprintf(crash_info.pkgid, sizeof(crash_info.pkgid), "%s", basename(crash_info.cmd_line)); + if (get_appid(cinfo->cmd_line, cinfo->appid, sizeof(cinfo->appid)) < 0) { + snprintf(cinfo->appid, sizeof(cinfo->appid), "%s", basename(cinfo->cmd_line)); + snprintf(cinfo->pkgid, sizeof(cinfo->pkgid), "%s", basename(cinfo->cmd_line)); } else { - if (get_pkgid(crash_info.appid, crash_info.pkgid, sizeof(crash_info.pkgid)) < 0) - snprintf(crash_info.pkgid, sizeof(crash_info.pkgid), "%s", crash_info.appid); + if (get_pkgid(cinfo->appid, cinfo->pkgid, sizeof(cinfo->pkgid)) < 0) + snprintf(cinfo->pkgid, sizeof(cinfo->pkgid), "%s", cinfo->appid); } return 0; rm_temp: - remove_dir(crash_info.temp_dir, 1); + remove_dir(cinfo->temp_dir, 1); return -1; } #ifdef SYS_ASSERT -static int get_sysassert_cs(void) +static int get_sysassert_cs(struct crash_info *cinfo) { int ret; char move_path[PATH_MAX]; - if (access(crash_info.sysassert_cs_path, F_OK)) { + if (access(cinfo->sysassert_cs_path, F_OK)) { _E("The sys-assert cs file not found: %s", - crash_info.sysassert_cs_path); - crash_info.have_sysassert_report = 0; + cinfo->sysassert_cs_path); + cinfo->have_sysassert_report = 0; return -1; } else - crash_info.have_sysassert_report = 1; + cinfo->have_sysassert_report = 1; ret = snprintf(move_path, sizeof(move_path), "%s/%s", - crash_info.pfx, basename(crash_info.sysassert_cs_path)); + cinfo->pfx, basename(cinfo->sysassert_cs_path)); if (ret < 0) { _E("Failed to snprintf for move path"); return -1; } - if (move_file(crash_info.sysassert_cs_path, move_path) < 0) { + if (move_file(cinfo->sysassert_cs_path, move_path) < 0) { _E("Failed to move %s to %s", - crash_info.sysassert_cs_path, move_path); + cinfo->sysassert_cs_path, move_path); return -1; } @@ -638,7 +638,7 @@ static int get_sysassert_cs(void) } #endif -static void launch_crash_popup(void) +static void launch_crash_popup(struct crash_info *cinfo) { GDBusConnection *conn; GVariantBuilder *builder; @@ -657,8 +657,8 @@ static void launch_crash_popup(void) builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); g_variant_builder_add(builder, "{ss}", "_SYSPOPUP_CONTENT_", "crash"); g_variant_builder_add(builder, "{ss}", "_PROCESS_NAME_", - basename(crash_info.cmd_line)); - g_variant_builder_add(builder, "{ss}", "_EXEPATH_", crash_info.cmd_path); + basename(cinfo->cmd_line)); + g_variant_builder_add(builder, "{ss}", "_EXEPATH_", cinfo->cmd_path); parameters = g_variant_new("(a{ss})", builder); g_variant_builder_unref(builder); @@ -689,14 +689,14 @@ exit: g_variant_unref(parameters); } -static int dump_system_state(void) +static int dump_system_state(const struct crash_info *cinfo) { int ret; char command[PATH_MAX]; ret = snprintf(command, sizeof(command), "/usr/bin/dump_systemstate -d -k -j -f %s", - crash_info.log_path); + cinfo->log_path); if (ret < 0) { _E("Failed to snprintf for dump_systemstate command"); return -1; @@ -705,52 +705,52 @@ static int dump_system_state(void) return system_command_parallel(command); } -static void copy_maps() +static void copy_maps(const struct crash_info *cinfo) { char maps_path[PATH_MAX]; char temp_maps_path[PATH_MAX]; snprintf(maps_path, sizeof(maps_path), "/proc/%d/maps", - crash_info.pid_info); + cinfo->pid_info); snprintf(temp_maps_path, sizeof(temp_maps_path), "%s/%s", - crash_info.temp_dir, TEMP_MAPS_FILENAME); + cinfo->temp_dir, TEMP_MAPS_FILENAME); copy_file(maps_path, temp_maps_path); } -static void remove_maps() +static void remove_maps(const struct crash_info *cinfo) { char temp_maps_path[PATH_MAX]; snprintf(temp_maps_path, sizeof(temp_maps_path), "%s/%s", - crash_info.temp_dir, TEMP_MAPS_FILENAME); + cinfo->temp_dir, TEMP_MAPS_FILENAME); if (unlink(temp_maps_path) < 0) _E("Cannot remove %s: %m\n", temp_maps_path); } -static void save_so_info() +static void save_so_info(const struct crash_info *cinfo) { char maps_path[PATH_MAX]; char so_info_path[PATH_MAX]; snprintf(maps_path, sizeof(maps_path), "%s/%s", - crash_info.temp_dir, TEMP_MAPS_FILENAME); + cinfo->temp_dir, TEMP_MAPS_FILENAME); snprintf(so_info_path, sizeof(so_info_path), - "%s/%s.%s", crash_info.pfx, crash_info.name, "so_info"); + "%s/%s.%s", cinfo->pfx, cinfo->name, "so_info"); get_and_save_so_info(maps_path, so_info_path); } -static int execute_minicoredump() +static int execute_minicoredump(struct crash_info *cinfo) { -#define SNPRINTF_OR_EXIT(name, format) if (snprintf(name##_str, sizeof(name##_str), format, crash_info.name##_info) < 0) goto out; +#define SNPRINTF_OR_EXIT(name, format) if (snprintf(name##_str, sizeof(name##_str), format, cinfo->name##_info) < 0) goto out; char *coredump_name = NULL; char *prstatus_fd_str = NULL; int ret = -1; - if (asprintf(&coredump_name, "%s.coredump", crash_info.name) == -1 - || asprintf(&prstatus_fd_str, "%d", crash_info.prstatus_fd) == -1) { + if (asprintf(&coredump_name, "%s.coredump", cinfo->name) == -1 + || asprintf(&prstatus_fd_str, "%d", cinfo->prstatus_fd) == -1) { _E("Unable to allocate memory"); goto out; } @@ -775,7 +775,7 @@ static int execute_minicoredump() "core", // %e - exe name (need for result filename) MINICOREDUMPER_CONFIG_PATH, // config file "-d", - crash_info.pfx, // temp dir + cinfo->pfx, // temp dir "-o", coredump_name, // coredump filename "-P", @@ -797,7 +797,7 @@ static int execute_minicoredump() if (!dump_core) { int ret = -1; int errno_unlink = 0; - int dirfd = open(crash_info.pfx, O_DIRECTORY); + int dirfd = open(cinfo->pfx, O_DIRECTORY); if (dirfd != -1) { ret = unlinkat(dirfd, coredump_name, 0); errno_unlink = errno; @@ -807,10 +807,10 @@ static int execute_minicoredump() if (ret != 0) _E("Saving core disabled - removing coredump %s/%s failed: %m", - crash_info.pfx, coredump_name); + cinfo->pfx, coredump_name); else _D("Saving core disabled - removed coredump %s/%s", - crash_info.pfx, coredump_name); + cinfo->pfx, coredump_name); } out: @@ -821,7 +821,7 @@ out: #undef SNPRINTF_OR_EXIT } -static void execute_crash_stack() +static void execute_crash_stack(const struct crash_info *cinfo) { int ret; char command[PATH_MAX]; @@ -830,11 +830,11 @@ static void execute_crash_stack() ret = snprintf(command, sizeof(command), "%s --pid %d --tid %d --sig %d --prstatus_fd %d > %s", CRASH_STACK_PATH, - crash_info.pid_info, - crash_info.tid_info, - crash_info.sig_info, - crash_info.prstatus_fd, - crash_info.info_path); + cinfo->pid_info, + cinfo->tid_info, + cinfo->sig_info, + cinfo->prstatus_fd, + cinfo->info_path); _D(" %s", command); if (ret < 0) { @@ -845,11 +845,11 @@ static void execute_crash_stack() system_command(command); } -static int execute_crash_modules() +static int execute_crash_modules(struct crash_info *cinfo) { _D("Execute crash module: "); - if (execute_minicoredump() < 0) { + if (execute_minicoredump(cinfo) < 0) { _E("Failed to run minicoredumper - can not continue"); return -1; } @@ -857,10 +857,10 @@ static int execute_crash_modules() #ifdef SYS_ASSERT /* Use process_vm_readv() version as fallback if sys-assert * failed to generate report */ - if (crash_info.have_sysassert_report) + if (cinfo->have_sysassert_report) return -1; #endif - execute_crash_stack(); + execute_crash_stack(cinfo); return 0; } @@ -1100,21 +1100,21 @@ static void clean_dump(void) free(dump_list); } -static void compress(void) +static void compress(struct crash_info *cinfo) { int ret, lock_fd; char zip_path[PATH_MAX]; char command[PATH_MAX]; ret = snprintf(zip_path, sizeof(zip_path), "%s/report.zip", - crash_info.temp_dir); + cinfo->temp_dir); if (ret < 0) { _E("Failed to snprintf for zip path"); return; } ret = snprintf(command, sizeof(command), "cd %s && /bin/zip -y -r %s %s > /dev/null 2>&1", - crash_info.temp_dir, zip_path, crash_info.name); + cinfo->temp_dir, zip_path, cinfo->name); if (ret < 0) { _E("Failed to snprintf for zip command"); return; @@ -1123,50 +1123,50 @@ static void compress(void) if ((lock_fd = lock_dumpdir()) < 0) return; - if (!rename(zip_path, crash_info.result_path)) + if (!rename(zip_path, cinfo->result_path)) clean_dump(); else - _E("Failed to move %s to %s", zip_path, crash_info.result_path); + _E("Failed to move %s to %s", zip_path, cinfo->result_path); unlock_dumpdir(lock_fd); - if (remove_dir(crash_info.temp_dir, 1) < 0) + if (remove_dir(cinfo->temp_dir, 1) < 0) _E("Failed to delete temp directory"); } -static void move_dump_dir(void) +static void move_dump_dir(const struct crash_info *cinfo) { int lock_fd; if ((lock_fd = lock_dumpdir()) < 0) return; - if (!rename(crash_info.pfx, crash_info.result_path)) + if (!rename(cinfo->pfx, cinfo->result_path)) clean_dump(); else _E("Failed to move %s to %s", - crash_info.pfx, crash_info.result_path); + cinfo->pfx, cinfo->result_path); unlock_dumpdir(lock_fd); - if (remove_dir(crash_info.temp_dir, 1) < 0) + if (remove_dir(cinfo->temp_dir, 1) < 0) _E("Failed to delete temp directory"); } -static void move_info_file(void) +static void move_info_file(struct crash_info *cinfo) { int lock_fd; if ((lock_fd = lock_dumpdir()) < 0) return; - snprintf(crash_info.result_path, sizeof(crash_info.result_path), "%s/%s.info", - crash_crash_path, crash_info.name); - if (!rename(crash_info.info_path, crash_info.result_path)) + snprintf(cinfo->result_path, sizeof(cinfo->result_path), "%s/%s.info", + crash_crash_path, cinfo->name); + if (!rename(cinfo->info_path, cinfo->result_path)) clean_dump(); else _E("Failed to move %s to %s", - crash_info.info_path, crash_info.result_path); + cinfo->info_path, cinfo->result_path); unlock_dumpdir(lock_fd); - if (remove_dir(crash_info.temp_dir, 1) < 0) + if (remove_dir(cinfo->temp_dir, 1) < 0) _E("Failed to delete temp directory"); } @@ -1190,6 +1190,8 @@ static int wait_for_opt(unsigned int timeout) int main(int argc, char *argv[]) { + struct crash_info cinfo; + /* Execute dump_systemstate in parallel */ static int dump_state_pid; int debug_mode = access(DEBUGMODE_PATH, F_OK) == 0; @@ -1225,64 +1227,64 @@ int main(int argc, char *argv[]) } /* Set crash info */ - if (set_crash_info(argc, argv) < 0) { + if (set_crash_info(&cinfo, argc, argv) < 0) { res = EXIT_FAILURE; goto exit; } #ifdef SYS_ASSERT /* Fetch callstack of sys-assert */ - get_sysassert_cs(); + get_sysassert_cs(&cinfo); #endif if (report_type >= REP_TYPE_FULL) { /* Exec dump_systemstate */ - dump_state_pid = dump_system_state(); + dump_state_pid = dump_system_state(&cinfo); /* Copy maps file to temp dir */ - copy_maps(); + copy_maps(&cinfo); } /* Exec crash modules */ - if (execute_crash_modules() < 0) { + if (execute_crash_modules(&cinfo) < 0) { res = EXIT_FAILURE; goto exit; } if (report_type >= REP_TYPE_FULL) { /* Save shared objects info (file names, bulid IDs, rpm package names) */ - save_so_info(); - remove_maps(); + save_so_info(&cinfo); + remove_maps(&cinfo); /* Wait dump_system_state */ wait_system_command(dump_state_pid); /* Tar compression */ if (allow_zip) - compress(); + compress(&cinfo); else - move_dump_dir(); + move_dump_dir(&cinfo); } else { - move_info_file(); + move_info_file(&cinfo); } /* launch crash-popup only if the .debugmode file is exist*/ if (debug_mode) - launch_crash_popup(); + launch_crash_popup(&cinfo); struct NotifyParams notify_params = { - .prstatus_fd = crash_info.prstatus_fd, - .pid = crash_info.pid_info, - .tid = crash_info.tid_info, - .cmd_name = basename(crash_info.cmd_line), - .cmd_path = crash_info.cmd_path, - .report_path = crash_info.result_path, - .appid = crash_info.appid, - .pkgid = crash_info.pkgid + .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); exit: - close(crash_info.prstatus_fd); + close(cinfo.prstatus_fd); free(crash_temp_path); free(crash_root_path); free(crash_crash_path); -- 2.7.4