summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunmin Lee <sunm.lee@samsung.com>2017-01-06 09:37:33 +0900
committerSunmin Lee <sunm.lee@samsung.com>2017-02-17 19:01:49 +0900
commit82e3caa86dee735d136b1e76af9e131a6896783a (patch)
tree630013368c404ba277b3dec026988cd3eb11b8dc
parent1fd58dbf78a8c819913a0293f763912b9cc253ac (diff)
downloadcrash-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.c81
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;