From c463ba45c42b4e2d8ce30c02a626d7183102f46e Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Wed, 9 Mar 2016 14:35:54 -0800 Subject: 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 --- libbacktrace/BacktraceCurrent.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'libbacktrace/BacktraceCurrent.cpp') 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 #include +#include + #include #include @@ -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); -- cgit v1.2.3