blob: 9310a4452ea12e78f59e4c4bc77416e3461ac6a7 [file] [log] [blame]
Christopher Ferris17e91d42013-10-21 13:30:52 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _LIBBACKTRACE_BACKTRACE_THREAD_H
18#define _LIBBACKTRACE_BACKTRACE_THREAD_H
19
20#include <inttypes.h>
Christopher Ferrisaa63d9f2014-04-29 09:35:30 -070021#include <signal.h>
Christopher Ferris17e91d42013-10-21 13:30:52 -070022#include <sys/types.h>
23
Christopher Ferrisdf290612014-01-22 19:21:07 -080024#include "BacktraceImpl.h"
Christopher Ferris17e91d42013-10-21 13:30:52 -070025
Christopher Ferris46756822014-01-14 20:16:30 -080026enum state_e {
Christopher Ferris17e91d42013-10-21 13:30:52 -070027 STATE_WAITING = 0,
28 STATE_DUMPING,
29 STATE_DONE,
30 STATE_CANCEL,
Christopher Ferris46756822014-01-14 20:16:30 -080031};
Christopher Ferris17e91d42013-10-21 13:30:52 -070032
Christopher Ferrisaa63d9f2014-04-29 09:35:30 -070033// The signal used to cause a thread to dump the stack.
34#if defined(__GLIBC__)
35// GLIBC reserves __SIGRTMIN signals, so use SIGRTMIN to avoid errors.
36#define THREAD_SIGNAL SIGRTMIN
37#else
38#define THREAD_SIGNAL (__SIGRTMIN+1)
39#endif
40
Christopher Ferris17e91d42013-10-21 13:30:52 -070041class BacktraceThreadInterface;
42
Christopher Ferris8ed46272013-10-29 15:44:25 -070043struct ThreadEntry {
Christopher Ferris17e91d42013-10-21 13:30:52 -070044 ThreadEntry(
45 BacktraceThreadInterface* impl, pid_t pid, pid_t tid,
46 size_t num_ignore_frames);
47 ~ThreadEntry();
48
Christopher Ferris8ed46272013-10-29 15:44:25 -070049 bool Match(pid_t chk_pid, pid_t chk_tid) { return (chk_pid == pid && chk_tid == tid); }
Christopher Ferris17e91d42013-10-21 13:30:52 -070050
51 static ThreadEntry* AddThreadToUnwind(
52 BacktraceThreadInterface* thread_intf, pid_t pid, pid_t tid,
53 size_t num_ignored_frames);
54
Christopher Ferris8ed46272013-10-29 15:44:25 -070055 BacktraceThreadInterface* thread_intf;
56 pid_t pid;
57 pid_t tid;
58 ThreadEntry* next;
59 ThreadEntry* prev;
60 int32_t state;
61 int num_ignore_frames;
Christopher Ferris17e91d42013-10-21 13:30:52 -070062};
63
64// Interface class that does not contain any local storage, only defines
65// virtual functions to be defined by subclasses.
66class BacktraceThreadInterface {
67public:
68 virtual ~BacktraceThreadInterface() { }
69
Christopher Ferris17e91d42013-10-21 13:30:52 -070070 virtual void ThreadUnwind(
71 siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames) = 0;
72};
73
74class BacktraceThread : public BacktraceCurrent {
75public:
76 // impl and thread_intf should point to the same object, this allows
77 // the compiler to catch if an implementation does not properly
78 // subclass both.
79 BacktraceThread(
Christopher Ferris98464972014-01-06 19:16:33 -080080 BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid,
Christopher Ferris46756822014-01-14 20:16:30 -080081 BacktraceMap* map);
Christopher Ferris17e91d42013-10-21 13:30:52 -070082 virtual ~BacktraceThread();
83
84 virtual bool Unwind(size_t num_ignore_frames);
85
86 virtual void ThreadUnwind(
87 siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames) {
88 thread_intf_->ThreadUnwind(siginfo, sigcontext, num_ignore_frames);
89 }
90
91private:
92 virtual bool TriggerUnwindOnThread(ThreadEntry* entry);
93
94 virtual void FinishUnwind();
95
96 BacktraceThreadInterface* thread_intf_;
97};
98
99#endif // _LIBBACKTRACE_BACKTRACE_THREAD_H