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#ifndef _LIBBACKTRACE_BACKTRACE_THREAD_H 1817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#define _LIBBACKTRACE_BACKTRACE_THREAD_H 1917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 2017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <inttypes.h> 21a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <pthread.h> 22aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#include <signal.h> 23a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <string.h> 2417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/types.h> 25a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris#include <ucontext.h> 2617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 27df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris#include "BacktraceImpl.h" 2817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 29aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris// The signal used to cause a thread to dump the stack. 30aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#if defined(__GLIBC__) 31aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris// GLIBC reserves __SIGRTMIN signals, so use SIGRTMIN to avoid errors. 32aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#define THREAD_SIGNAL SIGRTMIN 33aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#else 34aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#define THREAD_SIGNAL (__SIGRTMIN+1) 35aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#endif 36aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris 37a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisclass ThreadEntry { 38a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrispublic: 39a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris static ThreadEntry* Get(pid_t pid, pid_t tid, bool create = true); 4017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 41a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris static void Remove(ThreadEntry* entry); 4217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 43a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris void Wake(); 4417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 45a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris void Wait(int); 4617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 47e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris void CopyUcontextFromSigcontext(void*); 48e48460762273586744a79d146c2916bcfca7e9e4Christopher Ferris 49a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris inline void Lock() { 50a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_lock(&mutex_); 51db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris 52db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris // Always reset the wait value since this could be the first or nth 53db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris // time this entry is locked. 54db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris wait_value_ = 0; 55a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 5617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 57a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris inline void Unlock() { 58a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_unlock(&mutex_); 59a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 6017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 61a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris inline ucontext_t* GetUcontext() { return &ucontext_; } 6217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 63a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisprivate: 64a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry(pid_t pid, pid_t tid); 65a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ~ThreadEntry(); 6617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 67a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris bool Match(pid_t chk_pid, pid_t chk_tid) { return (chk_pid == pid_ && chk_tid == tid_); } 6817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 69a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pid_t pid_; 70a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pid_t tid_; 71a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris int ref_count_; 72a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_mutex_t mutex_; 73db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_mutex_t wait_mutex_; 74db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris pthread_cond_t wait_cond_; 75db44538387b08f367fc2419653639866f4c2fbd6Christopher Ferris int wait_value_; 76a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry* next_; 77a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ThreadEntry* prev_; 78a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ucontext_t ucontext_; 7917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 80a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris static ThreadEntry* list_; 81a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris static pthread_mutex_t list_mutex_; 82a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris}; 83a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 84a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrisclass BacktraceThread : public BacktraceCurrent { 85a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferrispublic: 86a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris BacktraceThread(BacktraceImpl* impl, pid_t tid, BacktraceMap* map); 87a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris virtual ~BacktraceThread(); 8817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 89a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris virtual bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext); 9017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris}; 9117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 9217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif // _LIBBACKTRACE_BACKTRACE_THREAD_H 93