gdbserver: Use std::list for all_processes
[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 struct inferior_list all_threads;
27
28 struct thread_info *current_thread;
29
30 #define get_thread(inf) ((struct thread_info *)(inf))
31
32 /* The current working directory used to start the inferior. */
33 static const char *current_inferior_cwd = NULL;
34
35 void
36 add_inferior_to_list (struct inferior_list *list,
37 struct inferior_list_entry *new_inferior)
38 {
39 new_inferior->next = NULL;
40 if (list->tail != NULL)
41 list->tail->next = new_inferior;
42 else
43 list->head = new_inferior;
44 list->tail = new_inferior;
45 }
46
47 /* Invoke ACTION for each inferior in LIST. */
48
49 void
50 for_each_inferior (struct inferior_list *list,
51 void (*action) (struct inferior_list_entry *))
52 {
53 struct inferior_list_entry *cur = list->head, *next;
54
55 while (cur != NULL)
56 {
57 next = cur->next;
58 (*action) (cur);
59 cur = next;
60 }
61 }
62
63 /* Invoke ACTION for each inferior in LIST, passing DATA to ACTION. */
64
65 void
66 for_each_inferior_with_data (struct inferior_list *list,
67 void (*action) (struct inferior_list_entry *,
68 void *),
69 void *data)
70 {
71 struct inferior_list_entry *cur = list->head, *next;
72
73 while (cur != NULL)
74 {
75 next = cur->next;
76 (*action) (cur, data);
77 cur = next;
78 }
79 }
80
81 void
82 remove_inferior (struct inferior_list *list,
83 struct inferior_list_entry *entry)
84 {
85 struct inferior_list_entry **cur;
86
87 if (list->head == entry)
88 {
89 list->head = entry->next;
90 if (list->tail == entry)
91 list->tail = list->head;
92 return;
93 }
94
95 cur = &list->head;
96 while (*cur && (*cur)->next != entry)
97 cur = &(*cur)->next;
98
99 if (*cur == NULL)
100 return;
101
102 (*cur)->next = entry->next;
103
104 if (list->tail == entry)
105 list->tail = *cur;
106 }
107
108 struct thread_info *
109 add_thread (ptid_t thread_id, void *target_data)
110 {
111 struct thread_info *new_thread = XCNEW (struct thread_info);
112
113 new_thread->entry.id = thread_id;
114 new_thread->last_resume_kind = resume_continue;
115 new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
116
117 add_inferior_to_list (&all_threads, &new_thread->entry);
118
119 if (current_thread == NULL)
120 current_thread = new_thread;
121
122 new_thread->target_data = target_data;
123
124 return new_thread;
125 }
126
127 /* Wrapper around get_first_inferior to return a struct thread_info *. */
128
129 struct thread_info *
130 get_first_thread (void)
131 {
132 return (struct thread_info *) get_first_inferior (&all_threads);
133 }
134
135 struct thread_info *
136 find_thread_ptid (ptid_t ptid)
137 {
138 return (struct thread_info *) find_inferior_id (&all_threads, ptid);
139 }
140
141 /* Find a thread associated with the given PROCESS, or NULL if no
142 such thread exists. */
143
144 static struct thread_info *
145 find_thread_process (const struct process_info *const process)
146 {
147 return find_any_thread_of_pid (process->pid);
148 }
149
150 /* Helper for find_any_thread_of_pid. Returns true if a thread
151 matches a PID. */
152
153 static int
154 thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
155 {
156 int pid = *(int *) pid_p;
157
158 return (ptid_get_pid (entry->id) == pid);
159 }
160
161 /* See gdbthread.h. */
162
163 struct thread_info *
164 find_any_thread_of_pid (int pid)
165 {
166 struct inferior_list_entry *entry;
167
168 entry = find_inferior (&all_threads, thread_of_pid, &pid);
169
170 return (struct thread_info *) entry;
171 }
172
173 static void
174 free_one_thread (struct inferior_list_entry *inf)
175 {
176 struct thread_info *thread = get_thread (inf);
177 free_register_cache (thread_regcache_data (thread));
178 free (thread);
179 }
180
181 void
182 remove_thread (struct thread_info *thread)
183 {
184 if (thread->btrace != NULL)
185 target_disable_btrace (thread->btrace);
186
187 discard_queued_stop_replies (ptid_of (thread));
188 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
189 free_one_thread (&thread->entry);
190 if (current_thread == thread)
191 current_thread = NULL;
192 }
193
194 /* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
195 This is for cases where the caller needs a thread, but doesn't care
196 which one. */
197
198 struct inferior_list_entry *
199 get_first_inferior (struct inferior_list *list)
200 {
201 if (list->head != NULL)
202 return list->head;
203 return NULL;
204 }
205
206 /* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
207 returns non-zero. If no entry is found then return NULL. */
208
209 struct inferior_list_entry *
210 find_inferior (struct inferior_list *list,
211 int (*func) (struct inferior_list_entry *, void *), void *arg)
212 {
213 struct inferior_list_entry *inf = list->head;
214
215 while (inf != NULL)
216 {
217 struct inferior_list_entry *next;
218
219 next = inf->next;
220 if ((*func) (inf, arg))
221 return inf;
222 inf = next;
223 }
224
225 return NULL;
226 }
227
228 /* Find the random inferior_list_entry E in LIST for which FUNC (E, ARG)
229 returns non-zero. If no entry is found then return NULL. */
230
231 struct inferior_list_entry *
232 find_inferior_in_random (struct inferior_list *list,
233 int (*func) (struct inferior_list_entry *, void *),
234 void *arg)
235 {
236 struct inferior_list_entry *inf = list->head;
237 int count = 0;
238 int random_selector;
239
240 /* First count how many interesting entries we have. */
241 while (inf != NULL)
242 {
243 struct inferior_list_entry *next;
244
245 next = inf->next;
246 if ((*func) (inf, arg))
247 count++;
248 inf = next;
249 }
250
251 if (count == 0)
252 return NULL;
253
254 /* Now randomly pick an entry out of those. */
255 random_selector = (int)
256 ((count * (double) rand ()) / (RAND_MAX + 1.0));
257
258 inf = list->head;
259 while (inf != NULL)
260 {
261 struct inferior_list_entry *next;
262
263 next = inf->next;
264 if ((*func) (inf, arg) && (random_selector-- == 0))
265 return inf;
266 inf = next;
267 }
268
269 gdb_assert_not_reached ("failed to find an inferior in random.");
270 return NULL;
271 }
272
273 struct inferior_list_entry *
274 find_inferior_id (struct inferior_list *list, ptid_t id)
275 {
276 struct inferior_list_entry *inf = list->head;
277
278 while (inf != NULL)
279 {
280 if (ptid_equal (inf->id, id))
281 return inf;
282 inf = inf->next;
283 }
284
285 return NULL;
286 }
287
288 void *
289 thread_target_data (struct thread_info *thread)
290 {
291 return thread->target_data;
292 }
293
294 struct regcache *
295 thread_regcache_data (struct thread_info *thread)
296 {
297 return thread->regcache_data;
298 }
299
300 void
301 set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
302 {
303 thread->regcache_data = data;
304 }
305
306 /* Return true if LIST has exactly one entry. */
307
308 int
309 one_inferior_p (struct inferior_list *list)
310 {
311 return list->head != NULL && list->head == list->tail;
312 }
313
314 /* Reset head,tail of LIST, assuming all entries have already been freed. */
315
316 void
317 clear_inferior_list (struct inferior_list *list)
318 {
319 list->head = NULL;
320 list->tail = NULL;
321 }
322
323 void
324 clear_inferiors (void)
325 {
326 for_each_inferior (&all_threads, free_one_thread);
327 clear_inferior_list (&all_threads);
328
329 clear_dlls ();
330
331 current_thread = NULL;
332 }
333
334 struct process_info *
335 add_process (int pid, int attached)
336 {
337 struct process_info *process = XCNEW (struct process_info);
338
339 process->pid = pid;
340 process->attached = attached;
341
342 all_processes.push_back (process);
343
344 return process;
345 }
346
347 /* Remove a process from the common process list and free the memory
348 allocated for it.
349 The caller is responsible for freeing private data first. */
350
351 void
352 remove_process (struct process_info *process)
353 {
354 clear_symbol_cache (&process->symbol_cache);
355 free_all_breakpoints (process);
356 gdb_assert (find_thread_process (process) == NULL);
357 all_processes.remove (process);
358 VEC_free (int, process->syscalls_to_catch);
359 free (process);
360 }
361
362 process_info *
363 find_process_pid (int pid)
364 {
365 return find_process ([&] (process_info *process) {
366 return process->pid == pid;
367 });
368 }
369
370 /* Get the first process in the process list, or NULL if the list is empty. */
371
372 process_info *
373 get_first_process (void)
374 {
375 if (!all_processes.empty ())
376 return all_processes.front ();
377 else
378 return NULL;
379 }
380
381 /* Return non-zero if there are any inferiors that we have created
382 (as opposed to attached-to). */
383
384 int
385 have_started_inferiors_p (void)
386 {
387 return find_process ([] (process_info *process) {
388 return !process->attached;
389 }) != NULL;
390 }
391
392 /* Return non-zero if there are any inferiors that we have attached to. */
393
394 int
395 have_attached_inferiors_p (void)
396 {
397 return find_process ([] (process_info *process) {
398 return process->attached;
399 }) != NULL;
400 }
401
402 struct process_info *
403 get_thread_process (const struct thread_info *thread)
404 {
405 int pid = ptid_get_pid (thread->entry.id);
406 return find_process_pid (pid);
407 }
408
409 struct process_info *
410 current_process (void)
411 {
412 gdb_assert (current_thread != NULL);
413 return get_thread_process (current_thread);
414 }
415
416 static void
417 do_restore_current_thread_cleanup (void *arg)
418 {
419 current_thread = (struct thread_info *) arg;
420 }
421
422 struct cleanup *
423 make_cleanup_restore_current_thread (void)
424 {
425 return make_cleanup (do_restore_current_thread_cleanup, current_thread);
426 }
427
428 /* See common/common-gdbthread.h. */
429
430 void
431 switch_to_thread (ptid_t ptid)
432 {
433 gdb_assert (ptid != minus_one_ptid);
434 current_thread = find_thread_ptid (ptid);
435 }
436
437 /* See common/common-inferior.h. */
438
439 const char *
440 get_inferior_cwd ()
441 {
442 return current_inferior_cwd;
443 }
444
445 /* See common/common-inferior.h. */
446
447 void
448 set_inferior_cwd (const char *cwd)
449 {
450 xfree ((void *) current_inferior_cwd);
451 if (cwd != NULL)
452 current_inferior_cwd = xstrdup (cwd);
453 else
454 current_inferior_cwd = NULL;
455 }
This page took 0.039799 seconds and 5 git commands to generate.