summaryrefslogtreecommitdiff
path: root/src/crash-stack
diff options
context:
space:
mode:
authorAdrian Szyndela <adrian.s@samsung.com>2016-12-16 13:27:35 +0100
committerƁukasz Stelmach <l.stelmach@samsung.com>2016-12-20 13:39:10 +0100
commit37b99923a1301b3c1a82e1b5616814a3c108fd2f (patch)
tree648d8864d98d11ba939bd2c3c2b3cbf286139ba7 /src/crash-stack
parentb42ab743f0bf4695b894b27018a17620ad706e8e (diff)
downloadcrash-worker-37b99923a1301b3c1a82e1b5616814a3c108fd2f.tar.gz
crash-worker-37b99923a1301b3c1a82e1b5616814a3c108fd2f.tar.bz2
crash-worker-37b99923a1301b3c1a82e1b5616814a3c108fd2f.zip
crash-stack: fixed attaching to thread
It is not necessary to attach to parent process main thread to resolve stack in another thread. This commit also solves hanging up on 'D' (and 'Z') processes - main thread is not attachable, when a crash occurs in another thread. Change-Id: Ic3a085951acb4057fcdd4a476693954d1d3a522b
Diffstat (limited to 'src/crash-stack')
-rw-r--r--src/crash-stack/crash-stack.c51
1 files changed, 23 insertions, 28 deletions
diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c
index 63a2b4a..894e876 100644
--- a/src/crash-stack/crash-stack.c
+++ b/src/crash-stack/crash-stack.c
@@ -290,14 +290,14 @@ void __find_symbol_in_elf(ProcInfo *proc_info, Dwarf_Addr mapping_start)
close(fd);
}
-static int __attachable(pid_t pid)
+static int __attachable(pid_t pid, pid_t tid)
{
/* read /proc/<pid>/stat */
- char buf[20];
+ char buf[40];
FILE *f;
char status;
- snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
+ snprintf(buf, sizeof(buf), "/proc/%d/task/%d/stat", pid, tid);
f = fopen(buf, "r");
if (NULL == f)
@@ -312,13 +312,13 @@ static int __attachable(pid_t pid)
return status != 'D';
}
-static void __print_proc_file(pid_t pid, const char *name)
+static void __print_proc_file(pid_t pid, pid_t tid, const char *name)
{
char buf[1024];
FILE *f;
int r;
- snprintf(buf, sizeof(buf), "/proc/%d/%s", pid, name);
+ snprintf(buf, sizeof(buf), "/proc/%d/task/%d/%s", pid, tid, name);
fprintf(outputfile, "%s:\n", buf);
@@ -339,14 +339,14 @@ static void __print_proc_file(pid_t pid, const char *name)
fprintf(outputfile, "\n");
}
-static void __print_not_attachable_process_info(pid_t pid)
+static void __print_not_attachable_process_info(pid_t pid, pid_t tid)
{
- fprintf(outputfile, "ERROR: can't attach to process %d - process is in uninterruptible sleep state\n", pid);
+ fprintf(outputfile, "ERROR: can't attach to process %d, thread %d - thread is in uninterruptible sleep state\n", pid, tid);
fprintf(outputfile, "Giving some /proc info instead:\n\n");
- __print_proc_file(pid, "wchan");
+ __print_proc_file(pid, tid, "wchan");
fprintf(outputfile, "\n");
- __print_proc_file(pid, "syscall");
- __print_proc_file(pid, "stack");
+ __print_proc_file(pid, tid, "syscall");
+ __print_proc_file(pid, tid, "stack");
}
/**
@@ -360,16 +360,16 @@ static Dwfl *__open_dwfl_with_pid(pid_t pid, pid_t tid)
int status;
pid_t stopped_pid;
- status = __attachable(pid);
+ status = __attachable(pid, tid);
if (-1 == status)
{
- fprintf(errfile, "failed to read /proc/%d/stat: %m\n", pid);
+ fprintf(errfile, "failed to read /proc/%d/task/%d/stat: %m\n", pid, tid);
return NULL;
}
if (!status)
{
- __print_not_attachable_process_info(pid);
+ __print_not_attachable_process_info(pid, tid);
return NULL;
}
@@ -378,23 +378,18 @@ static Dwfl *__open_dwfl_with_pid(pid_t pid, pid_t tid)
return NULL;
}
- if (pid != tid)
- if (ptrace(PTRACE_SEIZE, pid, NULL, PTRACE_O_TRACEEXIT) != 0) {
- fprintf(errfile, "PTRACE_SEIZE failed on PID %d: %m\n", pid);
- return NULL;
- }
-
ptrace(PTRACE_INTERRUPT, tid, 0, 0);
- ptrace(PTRACE_INTERRUPT, pid, 0, 0);
- stopped_pid = waitpid(pid, &status, 0);
- if (stopped_pid == -1 || stopped_pid != pid || !WIFSTOPPED(status)) {
+ stopped_pid = waitpid(tid, &status, __WALL);
+ if (stopped_pid == -1 || stopped_pid != tid || !WIFSTOPPED(status)) {
fprintf(errfile, "waitpid failed: %m, stopped_pid=%d, status=%d\n", stopped_pid, status);
return NULL;
}
- if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &__siginfo) != 0)
+ if (ptrace(PTRACE_GETSIGINFO, tid, NULL, &__siginfo) != 0) {
+ fprintf(errfile, "ptrace GETSIGINFO failed: %m, pid=%d, tid=%d\n", pid, tid);
return NULL;
+ }
static const Dwfl_Callbacks proc_callbacks = {
.find_elf = dwfl_linux_proc_find_elf,
@@ -405,19 +400,19 @@ static Dwfl *__open_dwfl_with_pid(pid_t pid, pid_t tid)
Dwfl *dwfl = dwfl_begin(&proc_callbacks);
if (dwfl == NULL) {
- fprintf(errfile, "process %d : Can't start dwfl (%s)\n", pid, dwfl_errmsg(-1));
+ fprintf(errfile, "process %d : Can't start dwfl (%s)\n", tid, dwfl_errmsg(-1));
return NULL;
}
- if (dwfl_linux_proc_report(dwfl, pid) < 0) {
- fprintf(errfile, "process %d : dwfl report failed (%s)\n", pid, dwfl_errmsg(-1));
+ if (dwfl_linux_proc_report(dwfl, tid) < 0) {
+ fprintf(errfile, "process %d : dwfl report failed (%s)\n", tid, dwfl_errmsg(-1));
dwfl_end(dwfl);
return NULL;
}
#if _ELFUTILS_PREREQ(0,158)
- if (dwfl_linux_proc_attach(dwfl, pid, true) < 0) {
- fprintf(errfile, "process %d : dwfl attach failed (%s)\n", pid, dwfl_errmsg(-1));
+ if (dwfl_linux_proc_attach(dwfl, tid, true) < 0) {
+ fprintf(errfile, "process %d : dwfl attach failed (%s)\n", tid, dwfl_errmsg(-1));
dwfl_end(dwfl);
return NULL;
}