diff options
| author | Christopher Ferris <cferris@google.com> | 2016-03-09 14:35:54 -0800 |
|---|---|---|
| committer | Christopher Ferris <cferris@google.com> | 2016-03-10 14:14:43 -0800 |
| commit | c463ba45c42b4e2d8ce30c02a626d7183102f46e (patch) | |
| tree | 4e68f1cb0a203371c57ef864def5acc4178a5d7f /libbacktrace/BacktraceCurrent.cpp | |
| parent | 01d76eb1ecb943db042eb6618087c0e22588e6b3 (diff) | |
| download | system_core-c463ba45c42b4e2d8ce30c02a626d7183102f46e.tar.gz system_core-c463ba45c42b4e2d8ce30c02a626d7183102f46e.tar.bz2 system_core-c463ba45c42b4e2d8ce30c02a626d7183102f46e.zip | |
Add error reporting mechanism for failing Unwind.
Remove the logging of an error if a thread disappears before the unwind
can begin. This can happen, so allow the caller to determine if this
is really a problem worth logging.
Bug: 27449879
(cherry picked from commit 206a3b9798e3622c906a3cafdb113c271c1c927c)
Change-Id: If9e7cfeb6eb7b122679a734c1a9eacee8354ef18
Diffstat (limited to 'libbacktrace/BacktraceCurrent.cpp')
| -rw-r--r-- | libbacktrace/BacktraceCurrent.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp index 8e223668e..5173e2cc9 100644 --- a/libbacktrace/BacktraceCurrent.cpp +++ b/libbacktrace/BacktraceCurrent.cpp @@ -24,6 +24,8 @@ #include <ucontext.h> #include <unistd.h> +#include <stdlib.h> + #include <string> #include <backtrace/Backtrace.h> @@ -65,9 +67,11 @@ size_t BacktraceCurrent::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { bool BacktraceCurrent::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) { if (GetMap() == nullptr) { // Without a map object, we can't do anything. + error_ = BACKTRACE_UNWIND_ERROR_MAP_MISSING; return false; } + error_ = BACKTRACE_UNWIND_NO_ERROR; if (ucontext) { return UnwindFromContext(num_ignore_frames, ucontext); } @@ -138,11 +142,19 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { BACK_LOGE("sigaction failed: %s", strerror(errno)); ThreadEntry::Remove(entry); pthread_mutex_unlock(&g_sigaction_mutex); + error_ = BACKTRACE_UNWIND_ERROR_INTERNAL; return false; } if (tgkill(Pid(), Tid(), THREAD_SIGNAL) != 0) { - BACK_LOGE("tgkill %d failed: %s", Tid(), strerror(errno)); + // Do not emit an error message, this might be expected. Set the + // error and let the caller decide. + if (errno == ESRCH) { + error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; + } else { + error_ = BACKTRACE_UNWIND_ERROR_INTERNAL; + } + sigaction(THREAD_SIGNAL, &oldact, nullptr); ThreadEntry::Remove(entry); pthread_mutex_unlock(&g_sigaction_mutex); @@ -183,7 +195,13 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { BACK_LOGW("Timed out waiting for signal handler to indicate it finished."); } } else { - BACK_LOGE("Timed out waiting for signal handler to get ucontext data."); + // Check to see if the thread has disappeared. + if (tgkill(Pid(), Tid(), 0) == -1 && errno == ESRCH) { + error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; + } else { + error_ = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT; + BACK_LOGE("Timed out waiting for signal handler to get ucontext data."); + } } ThreadEntry::Remove(entry); |
