gdbserver: use std::list for all_threads
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
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
25 std::list<process_info *> all_processes;
26 std::list<thread_info *> all_threads;
27
28 struct thread_info *current_thread;
29
30 /* The current working directory used to start the inferior. */
31 static const char *current_inferior_cwd = NULL;
32
33 thread_info *
34 find_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
45 thread_info *
46 find_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
55 thread_info *
56 find_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
67 void
68 for_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
78 void
79 for_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
90 struct thread_info *
91 add_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
111 struct thread_info *
112 get_first_thread (void)
113 {
114 if (!all_threads.empty ())
115 return all_threads.front ();
116 else
117 return NULL;
118 }
119
120 struct thread_info *
121 find_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
129 static struct thread_info *
130 find_thread_process (const struct process_info *const process)
131 {
132 return find_any_thread_of_pid (process->pid);
133 }
134
135 /* Helper for find_any_thread_of_pid. Returns true if a thread
136 matches a PID. */
137
138 static int
139 thread_of_pid (thread_info *entry, void *pid_p)
140 {
141 int pid = *(int *) pid_p;
142
143 return (ptid_get_pid (entry->id) == pid);
144 }
145
146 /* See gdbthread.h. */
147
148 struct thread_info *
149 find_any_thread_of_pid (int pid)
150 {
151 return find_inferior (&all_threads, thread_of_pid, &pid);
152 }
153
154 static void
155 free_one_thread (thread_info *thread)
156 {
157 free_register_cache (thread_regcache_data (thread));
158 free (thread);
159 }
160
161 void
162 remove_thread (struct thread_info *thread)
163 {
164 if (thread->btrace != NULL)
165 target_disable_btrace (thread->btrace);
166
167 discard_queued_stop_replies (ptid_of (thread));
168 all_threads.remove (thread);
169 free_one_thread (thread);
170 if (current_thread == thread)
171 current_thread = NULL;
172 }
173
174 void *
175 thread_target_data (struct thread_info *thread)
176 {
177 return thread->target_data;
178 }
179
180 struct regcache *
181 thread_regcache_data (struct thread_info *thread)
182 {
183 return thread->regcache_data;
184 }
185
186 void
187 set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
188 {
189 thread->regcache_data = data;
190 }
191
192 void
193 clear_inferiors (void)
194 {
195 for_each_inferior (&all_threads, free_one_thread);
196 all_threads.clear ();
197
198 clear_dlls ();
199
200 current_thread = NULL;
201 }
202
203 struct process_info *
204 add_process (int pid, int attached)
205 {
206 struct process_info *process = XCNEW (struct process_info);
207
208 process->pid = pid;
209 process->attached = attached;
210
211 all_processes.push_back (process);
212
213 return process;
214 }
215
216 /* Remove a process from the common process list and free the memory
217 allocated for it.
218 The caller is responsible for freeing private data first. */
219
220 void
221 remove_process (struct process_info *process)
222 {
223 clear_symbol_cache (&process->symbol_cache);
224 free_all_breakpoints (process);
225 gdb_assert (find_thread_process (process) == NULL);
226 all_processes.remove (process);
227 VEC_free (int, process->syscalls_to_catch);
228 free (process);
229 }
230
231 process_info *
232 find_process_pid (int pid)
233 {
234 return find_process ([&] (process_info *process) {
235 return process->pid == pid;
236 });
237 }
238
239 /* Get the first process in the process list, or NULL if the list is empty. */
240
241 process_info *
242 get_first_process (void)
243 {
244 if (!all_processes.empty ())
245 return all_processes.front ();
246 else
247 return NULL;
248 }
249
250 /* Return non-zero if there are any inferiors that we have created
251 (as opposed to attached-to). */
252
253 int
254 have_started_inferiors_p (void)
255 {
256 return find_process ([] (process_info *process) {
257 return !process->attached;
258 }) != NULL;
259 }
260
261 /* Return non-zero if there are any inferiors that we have attached to. */
262
263 int
264 have_attached_inferiors_p (void)
265 {
266 return find_process ([] (process_info *process) {
267 return process->attached;
268 }) != NULL;
269 }
270
271 struct process_info *
272 get_thread_process (const struct thread_info *thread)
273 {
274 return find_process_pid (thread->id.pid ());
275 }
276
277 struct process_info *
278 current_process (void)
279 {
280 gdb_assert (current_thread != NULL);
281 return get_thread_process (current_thread);
282 }
283
284 static void
285 do_restore_current_thread_cleanup (void *arg)
286 {
287 current_thread = (struct thread_info *) arg;
288 }
289
290 struct cleanup *
291 make_cleanup_restore_current_thread (void)
292 {
293 return make_cleanup (do_restore_current_thread_cleanup, current_thread);
294 }
295
296 /* See common/common-gdbthread.h. */
297
298 void
299 switch_to_thread (ptid_t ptid)
300 {
301 gdb_assert (ptid != minus_one_ptid);
302 current_thread = find_thread_ptid (ptid);
303 }
304
305 /* See common/common-inferior.h. */
306
307 const char *
308 get_inferior_cwd ()
309 {
310 return current_inferior_cwd;
311 }
312
313 /* See common/common-inferior.h. */
314
315 void
316 set_inferior_cwd (const char *cwd)
317 {
318 xfree ((void *) current_inferior_cwd);
319 if (cwd != NULL)
320 current_inferior_cwd = xstrdup (cwd);
321 else
322 current_inferior_cwd = NULL;
323 }
This page took 0.070724 seconds and 5 git commands to generate.