diff options
author | Mateusz Moscicki <m.moscicki2@partner.samsung.com> | 2018-08-14 15:42:02 +0200 |
---|---|---|
committer | Mateusz Moscicki <m.moscicki2@partner.samsung.com> | 2018-08-20 14:59:44 +0200 |
commit | 361e60c5feccbc4ecb6825177f7e536ea98737b4 (patch) | |
tree | 20ad1bf695665bc5b8e8dd8c5ba39d1881749b2b | |
parent | 24410fe4318dedadeec359606cd67551d9de238e (diff) | |
download | crash-worker-361e60c5feccbc4ecb6825177f7e536ea98737b4.tar.gz crash-worker-361e60c5feccbc4ecb6825177f7e536ea98737b4.tar.bz2 crash-worker-361e60c5feccbc4ecb6825177f7e536ea98737b4.zip |
Move finding TID to crash-manager
Additionally find_crash_tid() returns PID for single-threaded applications,
instead of -1.
Change-Id: Id6fcc652b95bddda954f25cd448f1e090918c231
-rw-r--r-- | src/crash-manager/crash-manager.c | 26 | ||||
-rw-r--r-- | src/crash-stack/crash-stack.c | 78 | ||||
-rw-r--r-- | src/shared/util.c | 78 | ||||
-rw-r--r-- | src/shared/util.h | 2 |
4 files changed, 105 insertions, 79 deletions
diff --git a/src/crash-manager/crash-manager.c b/src/crash-manager/crash-manager.c index 723d3d6..b23910c 100644 --- a/src/crash-manager/crash-manager.c +++ b/src/crash-manager/crash-manager.c @@ -506,8 +506,26 @@ static int set_crash_info(int argc, char *argv[]) crash_info.pid_info = argv[1]; crash_info.sig_info = argv[4]; - if (argc > 6) - crash_info.tid_info = argv[6]; + if (argc > 6) { + crash_info.tid_info = strdup(argv[6]); + if (crash_info.tid_info == NULL) { + _E("strdup error: %m"); + return -1; + } + } else { + crash_info.tid_info = NULL; + int pid = atoi(crash_info.pid_info); + int tid = find_crash_tid(pid); + if (tid < 0) { + _I("TID not found"); + tid = pid; + } + + if (asprintf(&crash_info.tid_info, "%d", tid) == -1) { + _E("asprintf error: %m"); + return -1; + } + } ret = get_cmd_info(&crash_info); if (ret <= 0) { @@ -757,9 +775,10 @@ static void execute_crash_stack(int argc, char *argv[]) crash_info.info_path); else ret = snprintf(command, sizeof(command), - "%s --pid %s --sig %s --prstatus_fd %d > %s", + "%s --pid %s --tid %s --sig %s --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); @@ -1169,6 +1188,7 @@ int main(int argc, char *argv[]) exit: close(crash_info.prstatus_fd); + free(crash_info.tid_info); free(crash_temp_path); free(crash_root_path); free(crash_crash_path); diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c index aa18a9a..e0e0a56 100644 --- a/src/crash-stack/crash-stack.c +++ b/src/crash-stack/crash-stack.c @@ -869,80 +869,6 @@ static void __print_buffer_info(FILE* bufferfile, FILE *outputfile) } /** - * @brief Check wchan of thread - * - * @param pid PID of the inspected process - * @param tid TID of the thread to check - */ -static int check_thread_wchan(int pid, int tid) -{ - int fd, cnt; - char path[PATH_MAX], buf[100]; - - snprintf(path, PATH_MAX, "/proc/%d/task/%d/wchan", pid, tid); - fd = open(path, O_RDONLY); - if (fd == -1) { - fprintf(errfile, "[crash-stack] cannot open %s\n", path); - return -errno; - } - cnt = read(fd, buf, sizeof(buf)); - if (cnt == -1 || cnt == sizeof(buf)) { - fprintf(errfile, "[crash-stack] read %s error\n", path); - close(fd); - return -errno; - } - buf[cnt] = 0; - close(fd); - - if (strncmp("do_coredump", buf, sizeof(buf)) == 0 || strncmp("pipe_wait", buf, sizeof(buf)) == 0) - return tid; - else - return 0; -} - -/** - * @brief Find crashed tid if tid was not offered - * - * @param pid PID of the inspected process - */ -static int find_crash_tid(int pid) -{ - int threadnum = 1; - int crash_tid = -1; - DIR *dir; - struct dirent *entry; - char task_path[PATH_MAX]; - struct stat sb; - - snprintf(task_path, PATH_MAX, "/proc/%d/task", pid); - if (stat(task_path, &sb) == -1) - return -1; - - threadnum = sb.st_nlink - 2; - - if (threadnum > 1) { - dir = opendir(task_path); - if (!dir) { - fprintf(errfile, "[crash-stack] cannot open %s\n", task_path); - return -1; - } else { - while ((entry = readdir(dir)) != NULL) { - if (strcmp(entry->d_name, ".") == 0 || - strcmp(entry->d_name, "..") == 0) - continue; - crash_tid = check_thread_wchan(pid, - atoi(entry->d_name)); - if (crash_tid > 0) - break; - } - closedir(dir); - return crash_tid; - } - } - return -1; -} - -/** * @brief Main function. * * Main module accepts should be launched with: @@ -993,8 +919,8 @@ int main(int argc, char **argv) if (NULL == outputfile) outputfile = stdout; if (tid == 0) { - if ((tid = find_crash_tid(pid)) < 0) - tid = pid; + fprintf(errfile, "TID not provided\n"); + return errno; } if (mkstemp(bufferfile_path) < 0) { diff --git a/src/shared/util.c b/src/shared/util.c index e18e943..f8982dc 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -514,6 +514,84 @@ int validate_file_name(char *name, int len) return 0; } + +/** + * @brief Check wchan of thread + * + * @param pid PID of the inspected process + * @param tid TID of the thread to check + */ +static int check_thread_wchan(int pid, int tid) +{ + int fd, cnt; + char path[PATH_MAX], buf[100]; + + snprintf(path, sizeof(path), "/proc/%d/task/%d/wchan", pid, tid); + fd = open(path, O_RDONLY); + if (fd == -1) { + _E("cannot open %s: %m\n", path); + return -errno; + } + cnt = read(fd, buf, sizeof(buf)); + if (cnt == -1 || cnt == sizeof(buf)) { + _E("read %s error: %m\n", path); + close(fd); + return -errno; + } + buf[cnt] = 0; + close(fd); + + if (strncmp("do_coredump", buf, sizeof(buf)) == 0 || strncmp("pipe_wait", buf, sizeof(buf)) == 0) + return tid; + else + return 0; +} + +/** + * @brief Find crashed tid if tid was not offered + * + * @param pid PID of the inspected process + */ +int find_crash_tid(int pid) +{ + int threadnum = 1; + int crash_tid = -1; + DIR *dir; + struct dirent *entry; + char task_path[PATH_MAX]; + struct stat sb; + + snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid); + if (stat(task_path, &sb) == -1) { + _E("no such file: %s", task_path); + return -1; + } + + threadnum = sb.st_nlink - 2; + + if (threadnum > 1) { + dir = opendir(task_path); + if (!dir) { + _E("cannot open %s\n", task_path); + return -1; + } else { + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + continue; + crash_tid = check_thread_wchan(pid, + atoi(entry->d_name)); + if (crash_tid > 0) + break; + } + closedir(dir); + return crash_tid; + } + } else if (threadnum == 1) { + return pid; + } + return -1; +} /** * @} */ diff --git a/src/shared/util.h b/src/shared/util.h index 85416fa..ddd90be 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -56,6 +56,8 @@ int get_directory_usage(char *path); int validate_env_name(char *name, int len); int validate_file_name(char *name, int len); + +int find_crash_tid(int pid); /** * @} */ |