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) {
char command[PATH_MAX];
/* Execute crash-stack */
- if (argc > 8)
- ret = snprintf(command, sizeof(command),
- "%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);
- else
- ret = snprintf(command, sizeof(command),
- "%s --pid %s --sig %s --prstatus_fd %d > %s",
- CRASH_STACK_PATH,
- crash_info.pid_info,
- crash_info.sig_info,
- crash_info.prstatus_fd,
- crash_info.info_path);
+ ret = snprintf(command, sizeof(command),
+ "%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);
+
_D(" %s", command);
if (ret < 0) {
_E("Failed to snprintf for crash-stack command");
exit:
close(crash_info.prstatus_fd);
+ free(crash_info.tid_info);
free(crash_temp_path);
free(crash_root_path);
free(crash_crash_path);
}
/**
- * @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) {
- _E("open(%s): %s", path, strerror(errno));
- return -errno;
- }
- cnt = read(fd, buf, sizeof(buf));
- if (cnt == -1 || cnt == sizeof(buf)) {
- _E("read(%s): %s", path, strerror(errno));
- 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) {
- _E("opendir(%s): %s", task_path, strerror(errno));
- 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:
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;
}
mode_t oldmode = umask(0077);
fclose(file);
return result;
}
+
+/**
+ * @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;
+}
/**
* @}
*/
int validate_file_name(char *name, int len);
int log_kmsg(char *fmt, ...);
+
+int find_crash_tid(int pid);
/**
* @}
*/