close(fd);
}
+static int __attachable(pid_t pid)
+{
+ /* read /proc/<pid>/stat */
+ char buf[20];
+ FILE *f;
+ char status;
+
+ snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
+
+ f = fopen(buf, "r");
+ if (NULL == f)
+ return -1;
+
+ /* check if status is D */
+ if (fscanf(f, "%*d %*s %c", &status) != 1)
+ return -1;
+
+ fclose(f);
+
+ return status != 'D';
+}
+
+static void __print_proc_file(pid_t pid, const char *name)
+{
+ char buf[1024];
+ FILE *f;
+ int r;
+
+ snprintf(buf, sizeof(buf), "/proc/%d/%s", pid, name);
+
+ fprintf(outputfile, "%s:\n", buf);
+
+ f = fopen(buf, "r");
+ if (NULL == f)
+ {
+ fprintf(errfile, "Failed to open %s: %m\n", buf);
+ return;
+ }
+
+ while ((r = fread(buf, 1, sizeof(buf), f)) > 0)
+ {
+ fwrite(buf, r, 1, outputfile);
+ }
+
+ fclose(f);
+
+ fprintf(outputfile, "\n");
+}
+
+static void __print_not_attachable_process_info(pid_t pid)
+{
+ fprintf(outputfile, "ERROR: can't attach to process %d - process is in uninterruptible sleep state\n", pid);
+ fprintf(outputfile, "Giving some /proc info instead:\n\n");
+ __print_proc_file(pid, "wchan");
+ fprintf(outputfile, "\n");
+ __print_proc_file(pid, "syscall");
+ __print_proc_file(pid, "stack");
+}
+
/**
* @brief Opens libdwfl for using with live process
*
int status;
pid_t stopped_pid;
+ status = __attachable(pid);
+ if (-1 == status)
+ {
+ fprintf(errfile, "failed to read /proc/%d/stat: %m\n", pid);
+ return NULL;
+ }
+
+ if (!status)
+ {
+ __print_not_attachable_process_info(pid);
+ return NULL;
+ }
+
if (ptrace(PTRACE_SEIZE, tid, NULL, PTRACE_O_TRACEEXIT) != 0) {
fprintf(errfile, "PTRACE_SEIZE failed on TID %d: %m\n", tid);
return NULL;