117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris/* 217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Copyright (C) 2013 The Android Open Source Project 317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * you may not use this file except in compliance with the License. 617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * You may obtain a copy of the License at 717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 1017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Unless required by applicable law or agreed to in writing, software 1117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * See the License for the specific language governing permissions and 1417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * limitations under the License. 1517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris */ 1617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 1717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <errno.h> 1817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <inttypes.h> 19a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <limits.h> 2017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <pthread.h> 2117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <signal.h> 22db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris#include <stdlib.h> 2317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <string.h> 24a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <sys/syscall.h> 25a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <sys/time.h> 2617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/types.h> 27a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <ucontext.h> 28db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris#include <unistd.h> 2917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 3017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <cutils/atomic.h> 3117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 32e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#include "BacktraceLog.h" 3317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include "BacktraceThread.h" 3417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include "thread_utils.h" 3517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 3617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 3717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// ThreadEntry implementation. 3817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 39a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher FerrisThreadEntry* ThreadEntry::list_ = NULL; 40a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrispthread_mutex_t ThreadEntry::list_mutex_ = PTHREAD_MUTEX_INITIALIZER; 41a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 42a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris// Assumes that ThreadEntry::list_mutex_ has already been locked before 43a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris// creating a ThreadEntry object. 44a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher FerrisThreadEntry::ThreadEntry(pid_t pid, pid_t tid) 45db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris : pid_(pid), tid_(tid), ref_count_(1), mutex_(PTHREAD_MUTEX_INITIALIZER), 46db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris wait_mutex_(PTHREAD_MUTEX_INITIALIZER), wait_value_(0), 47db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris next_(ThreadEntry::list_), prev_(NULL) { 48db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_condattr_t attr; 49db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_condattr_init(&attr); 50db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 51db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_cond_init(&wait_cond_, &attr); 52db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris 53a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Add ourselves to the list. 54a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (ThreadEntry::list_) { 55a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry::list_->prev_ = this; 56a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 57a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry::list_ = this; 5817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 5917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 60a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher FerrisThreadEntry* ThreadEntry::Get(pid_t pid, pid_t tid, bool create) { 61a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_lock(&ThreadEntry::list_mutex_); 62a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry* entry = list_; 63a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris while (entry != NULL) { 64a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (entry->Match(pid, tid)) { 65a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris break; 6617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 67a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry = entry->next_; 6817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 6917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 70a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (!entry) { 71a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (create) { 72a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry = new ThreadEntry(pid, tid); 73a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 74a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } else { 75a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry->ref_count_++; 76a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 77a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&ThreadEntry::list_mutex_); 78a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 79a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return entry; 8017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 8117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 82a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisvoid ThreadEntry::Remove(ThreadEntry* entry) { 83a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&entry->mutex_); 8417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 85a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_lock(&ThreadEntry::list_mutex_); 86a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (--entry->ref_count_ == 0) { 87a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris delete entry; 88a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 89a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&ThreadEntry::list_mutex_); 90a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris} 9117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 92a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris// Assumes that ThreadEntry::list_mutex_ has already been locked before 93a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris// deleting a ThreadEntry object. 94a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher FerrisThreadEntry::~ThreadEntry() { 95a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (list_ == this) { 96a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris list_ = next_; 97a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } else { 98a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (next_) { 99a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris next_->prev_ = prev_; 10017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 101a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris prev_->next_ = next_; 10217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 10317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 104a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris next_ = NULL; 105a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris prev_ = NULL; 106db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris 107db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_cond_destroy(&wait_cond_); 108a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris} 109a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 110a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisvoid ThreadEntry::Wait(int value) { 111a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris timespec ts; 112db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { 113db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris BACK_LOGW("clock_gettime failed: %s", strerror(errno)); 114db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris abort(); 11517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 116db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris ts.tv_sec += 10; 117db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris 118db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_mutex_lock(&wait_mutex_); 119db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris while (wait_value_ != value) { 120db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris int ret = pthread_cond_timedwait(&wait_cond_, &wait_mutex_, &ts); 121db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris if (ret != 0) { 122db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris BACK_LOGW("pthread_cond_timedwait failed: %s", strerror(ret)); 123db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris break; 124db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris } 125db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris } 126db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_mutex_unlock(&wait_mutex_); 127a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris} 12817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 129a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisvoid ThreadEntry::Wake() { 130db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_mutex_lock(&wait_mutex_); 131db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris wait_value_++; 132db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_mutex_unlock(&wait_mutex_); 133db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris 134db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_cond_signal(&wait_cond_); 13517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 13617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 137e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferrisvoid ThreadEntry::CopyUcontextFromSigcontext(void* sigcontext) { 138e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(sigcontext); 139e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris // The only thing the unwinder cares about is the mcontext data. 140e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris memcpy(&ucontext_.uc_mcontext, &ucontext->uc_mcontext, sizeof(ucontext->uc_mcontext)); 141e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris} 142e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris 14317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 14417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// BacktraceThread functions. 14517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris//------------------------------------------------------------------------- 146a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisstatic pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER; 14717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 148a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisstatic void SignalHandler(int, siginfo_t*, void* sigcontext) { 149a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false); 150a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (!entry) { 151a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris BACK_LOGW("Unable to find pid %d tid %d information", getpid(), gettid()); 152a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return; 15317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 154a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 155e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris entry->CopyUcontextFromSigcontext(sigcontext); 156a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 157a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Indicate the ucontext is now valid. 158a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry->Wake(); 159a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 160a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Pause the thread until the unwind is complete. This avoids having 161a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // the thread run ahead causing problems. 162db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris entry->Wait(2); 163a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 164a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry::Remove(entry); 16517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 16617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 167a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher FerrisBacktraceThread::BacktraceThread(BacktraceImpl* impl, pid_t tid, BacktraceMap* map) 168a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris : BacktraceCurrent(impl, map) { 16946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris tid_ = tid; 17017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 17117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 17217e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisBacktraceThread::~BacktraceThread() { 17317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 17417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 175a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisbool BacktraceThread::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) { 176a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (ucontext) { 177a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Unwind using an already existing ucontext. 178a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return impl_->Unwind(num_ignore_frames, ucontext); 17917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 18017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 181a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Prevent multiple threads trying to set the trigger action on different 182a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // threads at the same time. 183a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (pthread_mutex_lock(&g_sigaction_mutex) < 0) { 184a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris BACK_LOGW("sigaction failed: %s", strerror(errno)); 18517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 18617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 18717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 188a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry* entry = ThreadEntry::Get(Pid(), Tid()); 189a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry->Lock(); 190a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 191a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris struct sigaction act, oldact; 192a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris memset(&act, 0, sizeof(act)); 193a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris act.sa_sigaction = SignalHandler; 194a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 195a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris sigemptyset(&act.sa_mask); 196a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) { 197a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris BACK_LOGW("sigaction failed %s", strerror(errno)); 198a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry->Unlock(); 199a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry::Remove(entry); 200a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&g_sigaction_mutex); 201a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return false; 20217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 20317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 204a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris if (tgkill(Pid(), Tid(), THREAD_SIGNAL) != 0) { 205a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris BACK_LOGW("tgkill %d failed: %s", Tid(), strerror(errno)); 206a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris sigaction(THREAD_SIGNAL, &oldact, NULL); 207a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry->Unlock(); 208a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry::Remove(entry); 209a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&g_sigaction_mutex); 210a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return false; 21117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 21217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 213a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Wait for the thread to get the ucontext. 214db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris entry->Wait(1); 21517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 216a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // After the thread has received the signal, allow other unwinders to 217a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // continue. 218a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris sigaction(THREAD_SIGNAL, &oldact, NULL); 219a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&g_sigaction_mutex); 22017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 221a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris bool unwind_done = impl_->Unwind(num_ignore_frames, entry->GetUcontext()); 22217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 223a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Tell the signal handler to exit and release the entry. 224a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris entry->Wake(); 22517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 226a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris return unwind_done; 22717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 228