diff options
author | Sunmin Lee <sunm.lee@samsung.com> | 2017-01-06 09:37:33 +0900 |
---|---|---|
committer | Sunmin Lee <sunm.lee@samsung.com> | 2017-02-17 19:01:49 +0900 |
commit | 82e3caa86dee735d136b1e76af9e131a6896783a (patch) | |
tree | 630013368c404ba277b3dec026988cd3eb11b8dc | |
parent | 1fd58dbf78a8c819913a0293f763912b9cc253ac (diff) | |
download | crash-worker-82e3caa86dee735d136b1e76af9e131a6896783a.tar.gz crash-worker-82e3caa86dee735d136b1e76af9e131a6896783a.tar.bz2 crash-worker-82e3caa86dee735d136b1e76af9e131a6896783a.zip |
crash-stack: Find crashed tid by wchan
If tid is not offered by kernel, crash-stack would
find crashed tid by checking wchan value of each thread.
Change-Id: Idfd6866fe17af4c7a266b3ae127e39087b0848f0
Signed-off-by: Sunmin Lee <sunm.lee@samsung.com>
-rw-r--r-- | src/crash-stack/crash-stack.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c index 4e51472..3ea471b 100644 --- a/src/crash-stack/crash-stack.c +++ b/src/crash-stack/crash-stack.c @@ -800,6 +800,82 @@ static void __crash_stack_print_meminfo(FILE* outputfile, pid_t pid) } /** + * @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) + 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; + struct dirent *dentry = NULL; + 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 (readdir_r(dir, &entry, &dentry) == 0 && dentry) { + if (strcmp(dentry->d_name, ".") == 0 || + strcmp(dentry->d_name, "..") == 0) + continue; + crash_tid = check_thread_wchan(pid, + atoi(dentry->d_name)); + if (crash_tid > 0) + break; + } + closedir(dir); + return crash_tid; + } + } + return -1; +} + +/** * @brief Main function. * * Main module accepts should be launched with: @@ -841,7 +917,10 @@ int main(int argc, char **argv) if (NULL == errfile) errfile = stderr; if (NULL == outputfile) outputfile = stdout; - if (tid == 0) tid = pid; + if (tid == 0) { + if ((tid = find_crash_tid(pid)) < 0) + tid = pid; + } argc -= optind; |