Add overloads of for_each_thread/find_thread that filter on pid
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
... / ...
CommitLineData
1/* Inferior process information for the remote server for GDB.
2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
3
4 Contributed by MontaVista Software.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#include "server.h"
22#include "gdbthread.h"
23#include "dll.h"
24
25std::list<process_info *> all_processes;
26std::list<thread_info *> all_threads;
27
28struct thread_info *current_thread;
29
30/* The current working directory used to start the inferior. */
31static const char *current_inferior_cwd = NULL;
32
33thread_info *
34find_inferior (std::list<thread_info *> *thread_list,
35 int (*func) (thread_info *, void *),
36 void *arg)
37{
38 gdb_assert (thread_list == &all_threads);
39
40 return find_thread ([&] (thread_info *thread) {
41 return func (thread, arg);
42 });
43}
44
45thread_info *
46find_inferior_id (std::list<thread_info *> *thread_list, ptid_t id)
47{
48 gdb_assert (thread_list == &all_threads);
49
50 return find_thread ([&] (thread_info *thread) {
51 return thread->id == id;
52 });
53}
54
55thread_info *
56find_inferior_in_random (std::list<thread_info *> *thread_list,
57 int (*func) (thread_info *, void *),
58 void *arg)
59{
60 gdb_assert (thread_list == &all_threads);
61
62 return find_thread_in_random ([&] (thread_info *thread) {
63 return func (thread, arg);
64 });
65}
66
67void
68for_each_inferior (std::list<thread_info *> *thread_list,
69 void (*action) (thread_info *))
70{
71 gdb_assert (thread_list == &all_threads);
72
73 for_each_thread ([&] (thread_info *thread) {
74 action (thread);
75 });
76}
77
78void
79for_each_inferior_with_data (std::list<thread_info *> *thread_list,
80 void (*action) (thread_info *, void *),
81 void *data)
82{
83 gdb_assert (thread_list == &all_threads);
84
85 for_each_thread ([&] (thread_info *thread) {
86 action (thread, data);
87 });
88}
89
90struct thread_info *
91add_thread (ptid_t thread_id, void *target_data)
92{
93 struct thread_info *new_thread = XCNEW (struct thread_info);
94
95 new_thread->id = thread_id;
96 new_thread->last_resume_kind = resume_continue;
97 new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
98
99 all_threads.push_back (new_thread);
100
101 if (current_thread == NULL)
102 current_thread = new_thread;
103
104 new_thread->target_data = target_data;
105
106 return new_thread;
107}
108
109/* See gdbthread.h. */
110
111struct thread_info *
112get_first_thread (void)
113{
114 if (!all_threads.empty ())
115 return all_threads.front ();
116 else
117 return NULL;
118}
119
120struct thread_info *
121find_thread_ptid (ptid_t ptid)
122{
123 return (struct thread_info *) find_inferior_id (&all_threads, ptid);
124}
125
126/* Find a thread associated with the given PROCESS, or NULL if no
127 such thread exists. */
128
129static struct thread_info *
130find_thread_process (const struct process_info *const process)
131{
132 return find_any_thread_of_pid (process->pid);
133}
134
135/* See gdbthread.h. */
136
137struct thread_info *
138find_any_thread_of_pid (int pid)
139{
140 return find_thread (pid, [] (thread_info *thread) {
141 return true;
142 });
143}
144
145static void
146free_one_thread (thread_info *thread)
147{
148 free_register_cache (thread_regcache_data (thread));
149 free (thread);
150}
151
152void
153remove_thread (struct thread_info *thread)
154{
155 if (thread->btrace != NULL)
156 target_disable_btrace (thread->btrace);
157
158 discard_queued_stop_replies (ptid_of (thread));
159 all_threads.remove (thread);
160 free_one_thread (thread);
161 if (current_thread == thread)
162 current_thread = NULL;
163}
164
165void *
166thread_target_data (struct thread_info *thread)
167{
168 return thread->target_data;
169}
170
171struct regcache *
172thread_regcache_data (struct thread_info *thread)
173{
174 return thread->regcache_data;
175}
176
177void
178set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
179{
180 thread->regcache_data = data;
181}
182
183void
184clear_inferiors (void)
185{
186 for_each_inferior (&all_threads, free_one_thread);
187 all_threads.clear ();
188
189 clear_dlls ();
190
191 current_thread = NULL;
192}
193
194struct process_info *
195add_process (int pid, int attached)
196{
197 struct process_info *process = XCNEW (struct process_info);
198
199 process->pid = pid;
200 process->attached = attached;
201
202 all_processes.push_back (process);
203
204 return process;
205}
206
207/* Remove a process from the common process list and free the memory
208 allocated for it.
209 The caller is responsible for freeing private data first. */
210
211void
212remove_process (struct process_info *process)
213{
214 clear_symbol_cache (&process->symbol_cache);
215 free_all_breakpoints (process);
216 gdb_assert (find_thread_process (process) == NULL);
217 all_processes.remove (process);
218 VEC_free (int, process->syscalls_to_catch);
219 free (process);
220}
221
222process_info *
223find_process_pid (int pid)
224{
225 return find_process ([&] (process_info *process) {
226 return process->pid == pid;
227 });
228}
229
230/* Get the first process in the process list, or NULL if the list is empty. */
231
232process_info *
233get_first_process (void)
234{
235 if (!all_processes.empty ())
236 return all_processes.front ();
237 else
238 return NULL;
239}
240
241/* Return non-zero if there are any inferiors that we have created
242 (as opposed to attached-to). */
243
244int
245have_started_inferiors_p (void)
246{
247 return find_process ([] (process_info *process) {
248 return !process->attached;
249 }) != NULL;
250}
251
252/* Return non-zero if there are any inferiors that we have attached to. */
253
254int
255have_attached_inferiors_p (void)
256{
257 return find_process ([] (process_info *process) {
258 return process->attached;
259 }) != NULL;
260}
261
262struct process_info *
263get_thread_process (const struct thread_info *thread)
264{
265 return find_process_pid (thread->id.pid ());
266}
267
268struct process_info *
269current_process (void)
270{
271 gdb_assert (current_thread != NULL);
272 return get_thread_process (current_thread);
273}
274
275static void
276do_restore_current_thread_cleanup (void *arg)
277{
278 current_thread = (struct thread_info *) arg;
279}
280
281struct cleanup *
282make_cleanup_restore_current_thread (void)
283{
284 return make_cleanup (do_restore_current_thread_cleanup, current_thread);
285}
286
287/* See common/common-gdbthread.h. */
288
289void
290switch_to_thread (ptid_t ptid)
291{
292 gdb_assert (ptid != minus_one_ptid);
293 current_thread = find_thread_ptid (ptid);
294}
295
296/* See common/common-inferior.h. */
297
298const char *
299get_inferior_cwd ()
300{
301 return current_inferior_cwd;
302}
303
304/* See common/common-inferior.h. */
305
306void
307set_inferior_cwd (const char *cwd)
308{
309 xfree ((void *) current_inferior_cwd);
310 if (cwd != NULL)
311 current_inferior_cwd = xstrdup (cwd);
312 else
313 current_inferior_cwd = NULL;
314}
This page took 0.026602 seconds and 4 git commands to generate.