gdbserver: hide fork child threads from GDB
[deliverable/binutils-gdb.git] / gdbserver / gdbthread.h
CommitLineData
623b6bdf 1/* Multi-thread control defs for remote server for GDB.
3666a048 2 Copyright (C) 1993-2021 Free Software Foundation, Inc.
623b6bdf
YQ
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
1a5c2598
TT
19#ifndef GDBSERVER_GDBTHREAD_H
20#define GDBSERVER_GDBTHREAD_H
623b6bdf 21
268a13a5 22#include "gdbsupport/common-gdbthread.h"
6a6bbd9d 23#include "inferiors.h"
623b6bdf 24
9c80ecd6
SM
25#include <list>
26
9accd112 27struct btrace_target_info;
a44892be 28struct regcache;
9accd112 29
623b6bdf
YQ
30struct thread_info
31{
fa912657
SM
32 thread_info (ptid_t id, void *target_data)
33 : id (id), target_data (target_data)
34 {
35 this->last_status.kind = TARGET_WAITKIND_IGNORE;
36 }
37
38 ~thread_info ()
39 {
40 free_register_cache (this->regcache_data);
41 }
42
9c80ecd6
SM
43 /* The id of this thread. */
44 ptid_t id;
80894984 45
623b6bdf 46 void *target_data;
fa912657 47 struct regcache *regcache_data = nullptr;
623b6bdf
YQ
48
49 /* The last resume GDB requested on this thread. */
fa912657 50 enum resume_kind last_resume_kind = resume_continue;
623b6bdf
YQ
51
52 /* The last wait status reported for this thread. */
53 struct target_waitstatus last_status;
54
b7ea362b 55 /* True if LAST_STATUS hasn't been reported to GDB yet. */
fa912657 56 int status_pending_p = 0;
b7ea362b 57
623b6bdf
YQ
58 /* Given `while-stepping', a thread may be collecting data for more
59 than one tracepoint simultaneously. E.g.:
60
61 ff0001 INSN1 <-- TP1, while-stepping 10 collect $regs
62 ff0002 INSN2
63 ff0003 INSN3 <-- TP2, collect $regs
64 ff0004 INSN4 <-- TP3, while-stepping 10 collect $regs
65 ff0005 INSN5
66
67 Notice that when instruction INSN5 is reached, the while-stepping
68 actions of both TP1 and TP3 are still being collected, and that TP2
69 had been collected meanwhile. The whole range of ff0001-ff0005
70 should be single-stepped, due to at least TP1's while-stepping
71 action covering the whole range.
72
73 On the other hand, the same tracepoint with a while-stepping action
74 may be hit by more than one thread simultaneously, hence we can't
75 keep the current step count in the tracepoint itself.
76
77 This is the head of the list of the states of `while-stepping'
78 tracepoint actions this thread is now collecting; NULL if empty.
79 Each item in the list holds the current step of the while-stepping
80 action. */
fa912657 81 struct wstep_state *while_stepping = nullptr;
9accd112
MM
82
83 /* Branch trace target information for this thread. */
fa912657 84 struct btrace_target_info *btrace = nullptr;
edf56335
SM
85
86 /* A pointer to this thread's fork child or fork parent. Valid only while
87 the parent fork or vfork event is not reported to GDB.
88
89 Used to avoid wildcard vCont actions resuming a (v)fork child before GDB is
90 notified about the parent's (v)fork event. Also used to avoid including the
91 (v)fork child in thread list packet responses (e.g. qfThreadInfo). */
92 thread_info *fork_child = nullptr;
93 thread_info *fork_parent = nullptr;
623b6bdf
YQ
94};
95
9c80ecd6 96extern std::list<thread_info *> all_threads;
623b6bdf
YQ
97
98void remove_thread (struct thread_info *thread);
f7667f0d 99struct thread_info *add_thread (ptid_t ptid, void *target_data);
623b6bdf 100
9c80ecd6
SM
101/* Return a pointer to the first thread, or NULL if there isn't one. */
102
649ebbca
DE
103struct thread_info *get_first_thread (void);
104
623b6bdf 105struct thread_info *find_thread_ptid (ptid_t ptid);
623b6bdf 106
34c65914
PA
107/* Find any thread of the PID process. Returns NULL if none is
108 found. */
109struct thread_info *find_any_thread_of_pid (int pid);
110
9c80ecd6
SM
111/* Find the first thread for which FUNC returns true. Return NULL if no thread
112 satisfying FUNC is found. */
113
114template <typename Func>
115static thread_info *
116find_thread (Func func)
117{
118 std::list<thread_info *>::iterator next, cur = all_threads.begin ();
119
120 while (cur != all_threads.end ())
121 {
122 next = cur;
123 next++;
124
125 if (func (*cur))
126 return *cur;
127
128 cur = next;
129 }
130
131 return NULL;
132}
133
4d3bb80e
SM
134/* Like the above, but only consider threads with pid PID. */
135
136template <typename Func>
137static thread_info *
138find_thread (int pid, Func func)
139{
140 return find_thread ([&] (thread_info *thread)
141 {
142 return thread->id.pid () == pid && func (thread);
143 });
144}
145
6d1e5673
SM
146/* Find the first thread that matches FILTER for which FUNC returns true.
147 Return NULL if no thread satisfying these conditions is found. */
148
149template <typename Func>
150static thread_info *
151find_thread (ptid_t filter, Func func)
152{
153 return find_thread ([&] (thread_info *thread) {
154 return thread->id.matches (filter) && func (thread);
155 });
156}
157
9c80ecd6
SM
158/* Invoke FUNC for each thread. */
159
160template <typename Func>
161static void
162for_each_thread (Func func)
163{
164 std::list<thread_info *>::iterator next, cur = all_threads.begin ();
165
166 while (cur != all_threads.end ())
167 {
168 next = cur;
169 next++;
170 func (*cur);
171 cur = next;
172 }
173}
174
4d3bb80e
SM
175/* Like the above, but only consider threads with pid PID. */
176
177template <typename Func>
178static void
179for_each_thread (int pid, Func func)
180{
181 for_each_thread ([&] (thread_info *thread)
182 {
183 if (pid == thread->id.pid ())
184 func (thread);
185 });
186}
187
9c80ecd6
SM
188/* Find the a random thread for which FUNC (THREAD) returns true. If
189 no entry is found then return NULL. */
190
191template <typename Func>
192static thread_info *
193find_thread_in_random (Func func)
194{
195 int count = 0;
196 int random_selector;
197
198 /* First count how many interesting entries we have. */
199 for_each_thread ([&] (thread_info *thread) {
200 if (func (thread))
201 count++;
202 });
203
204 if (count == 0)
205 return NULL;
206
207 /* Now randomly pick an entry out of those. */
208 random_selector = (int)
209 ((count * (double) rand ()) / (RAND_MAX + 1.0));
210
da4ae14a
TT
211 thread_info *thread = find_thread ([&] (thread_info *thr_arg) {
212 return func (thr_arg) && (random_selector-- == 0);
9c80ecd6
SM
213 });
214
215 gdb_assert (thread != NULL);
216
217 return thread;
218}
219
fbd5db48 220/* Get current thread ID (Linux task ID). */
9c80ecd6 221#define current_ptid (current_thread->id)
f5a02773 222
9179355e
SM
223/* Get the ptid of THREAD. */
224
225static inline ptid_t
226ptid_of (const thread_info *thread)
227{
9c80ecd6 228 return thread->id;
9179355e
SM
229}
230
231/* Get the pid of THREAD. */
232
233static inline int
234pid_of (const thread_info *thread)
235{
9c80ecd6 236 return thread->id.pid ();
9179355e
SM
237}
238
239/* Get the lwp of THREAD. */
240
241static inline long
242lwpid_of (const thread_info *thread)
243{
9c80ecd6 244 return thread->id.lwp ();
9179355e
SM
245}
246
1a5c2598 247#endif /* GDBSERVER_GDBTHREAD_H */
This page took 0.71388 seconds and 4 git commands to generate.