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