diff options
author | Christopher Ferris <cferris@google.com> | 2015-09-03 11:25:55 -0700 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2015-09-03 19:06:06 -0700 |
commit | d9a06afb19156b61ee85c975a292d884bba09c7f (patch) | |
tree | 0ca95e795383225c224bd6c53673cb648b15aa23 /libbacktrace | |
parent | bc8c731aab0fce447e2b792f443aa5b6d72f55f2 (diff) | |
download | system_core-d9a06afb19156b61ee85c975a292d884bba09c7f.zip system_core-d9a06afb19156b61ee85c975a292d884bba09c7f.tar.gz system_core-d9a06afb19156b61ee85c975a292d884bba09c7f.tar.bz2 |
Add a logging handler on timeout.
If the signal handler doesn't fire in the given time when trying to unwind
a thread, put on a logging handler. This prevents crashes if the signal
does eventually fire.
Bug: 23783762
(cherry picked from commit d7226f9a1485ba19f714369fd7f8b444d66feb61)
Change-Id: Ib990a06733cc93717752ab4998f4ae26afd7e249
Diffstat (limited to 'libbacktrace')
-rw-r--r-- | libbacktrace/BacktraceCurrent.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp index 2714d93..d339550 100644 --- a/libbacktrace/BacktraceCurrent.cpp +++ b/libbacktrace/BacktraceCurrent.cpp @@ -93,6 +93,10 @@ bool BacktraceCurrent::DiscardFrame(const backtrace_frame_data_t& frame) { static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER; +static void SignalLogOnly(int, siginfo_t*, void*) { + BACK_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(), THREAD_SIGNAL); +} + static void SignalHandler(int, siginfo_t*, void* sigcontext) { ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false); if (!entry) { @@ -151,9 +155,21 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { // that we are waiting for the first Wake() call made by the thread. bool wait_completed = entry->Wait(1); + if (!wait_completed && oldact.sa_sigaction == nullptr) { + // If the wait failed, it could be that the signal could not be delivered + // within the timeout. Add a signal handler that's simply going to log + // something so that we don't crash if the signal eventually gets + // delivered. Only do this if there isn't already an action set up. + memset(&act, 0, sizeof(act)); + act.sa_sigaction = SignalLogOnly; + act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; + sigemptyset(&act.sa_mask); + sigaction(THREAD_SIGNAL, &act, nullptr); + } else { + sigaction(THREAD_SIGNAL, &oldact, nullptr); + } // After the thread has received the signal, allow other unwinders to // continue. - sigaction(THREAD_SIGNAL, &oldact, nullptr); pthread_mutex_unlock(&g_sigaction_mutex); bool unwind_done = false; |