gdbserver: don't pick a random thread if the current thread dies
[deliverable/binutils-gdb.git] / gdb / gdbserver / inferiors.c
CommitLineData
ce3a066d 1/* Inferior process information for the remote server for GDB.
32d0add0 2 Copyright (C) 2002-2015 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{
bca929d3 108 struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
0d62e5e8
DJ
109
110 memset (new_thread, 0, sizeof (*new_thread));
111
112 new_thread->entry.id = thread_id;
8336d594 113 new_thread->last_resume_kind = resume_continue;
fc7238bb 114 new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
0d62e5e8 115
ecc6f45c 116 add_inferior_to_list (&all_threads, &new_thread->entry);
255e7678 117
0bfdf32f
GB
118 if (current_thread == NULL)
119 current_thread = new_thread;
ce3a066d 120
0d62e5e8 121 new_thread->target_data = target_data;
f7667f0d
DE
122
123 return new_thread;
a06660f7
DJ
124}
125
95954743 126ptid_t
a06660f7
DJ
127thread_to_gdb_id (struct thread_info *thread)
128{
95954743 129 return thread->entry.id;
a06660f7
DJ
130}
131
649ebbca
DE
132/* Wrapper around get_first_inferior to return a struct thread_info *. */
133
dae5f5cf 134struct thread_info *
649ebbca 135get_first_thread (void)
a06660f7 136{
649ebbca
DE
137 return (struct thread_info *) get_first_inferior (&all_threads);
138}
a06660f7 139
649ebbca
DE
140struct thread_info *
141find_thread_ptid (ptid_t ptid)
142{
143 return (struct thread_info *) find_inferior_id (&all_threads, ptid);
dae5f5cf
DJ
144}
145
95954743
PA
146ptid_t
147gdb_id_to_thread_id (ptid_t gdb_id)
dae5f5cf 148{
e09875d4 149 struct thread_info *thread = find_thread_ptid (gdb_id);
dae5f5cf 150
95954743 151 return thread ? thread->entry.id : null_ptid;
0d62e5e8 152}
c04a1aa8 153
0d62e5e8
DJ
154static void
155free_one_thread (struct inferior_list_entry *inf)
156{
157 struct thread_info *thread = get_thread (inf);
158 free_register_cache (inferior_regcache_data (thread));
159 free (thread);
160}
161
162void
163remove_thread (struct thread_info *thread)
164{
9accd112
MM
165 if (thread->btrace != NULL)
166 target_disable_btrace (thread->btrace);
167
0d62e5e8
DJ
168 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
169 free_one_thread (&thread->entry);
ce3a066d
DJ
170}
171
649ebbca
DE
172/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
173 This is for cases where the caller needs a thread, but doesn't care
174 which one. */
175
176struct inferior_list_entry *
177get_first_inferior (struct inferior_list *list)
178{
3b8361aa
DE
179 if (list->head != NULL)
180 return list->head;
649ebbca
DE
181 return NULL;
182}
183
0718675c
JB
184/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
185 returns non-zero. If no entry is found then return NULL. */
186
0d62e5e8
DJ
187struct inferior_list_entry *
188find_inferior (struct inferior_list *list,
189 int (*func) (struct inferior_list_entry *, void *), void *arg)
190{
191 struct inferior_list_entry *inf = list->head;
ce3a066d 192
0d62e5e8 193 while (inf != NULL)
ce3a066d 194 {
a07b2135
PA
195 struct inferior_list_entry *next;
196
197 next = inf->next;
0d62e5e8
DJ
198 if ((*func) (inf, arg))
199 return inf;
a07b2135 200 inf = next;
0d62e5e8 201 }
611cb4a5 202
0d62e5e8
DJ
203 return NULL;
204}
611cb4a5 205
0d62e5e8 206struct inferior_list_entry *
95954743 207find_inferior_id (struct inferior_list *list, ptid_t id)
0d62e5e8
DJ
208{
209 struct inferior_list_entry *inf = list->head;
210
211 while (inf != NULL)
212 {
95954743 213 if (ptid_equal (inf->id, id))
0d62e5e8
DJ
214 return inf;
215 inf = inf->next;
ce3a066d
DJ
216 }
217
0d62e5e8 218 return NULL;
ce3a066d 219}
611cb4a5
DJ
220
221void *
0d62e5e8 222inferior_target_data (struct thread_info *inferior)
611cb4a5
DJ
223{
224 return inferior->target_data;
225}
226
227void
0d62e5e8 228set_inferior_target_data (struct thread_info *inferior, void *data)
611cb4a5
DJ
229{
230 inferior->target_data = data;
231}
c04a1aa8 232
a44892be 233struct regcache *
0d62e5e8 234inferior_regcache_data (struct thread_info *inferior)
c04a1aa8
DJ
235{
236 return inferior->regcache_data;
237}
238
239void
a44892be 240set_inferior_regcache_data (struct thread_info *inferior, struct regcache *data)
c04a1aa8
DJ
241{
242 inferior->regcache_data = data;
243}
255e7678 244
649ebbca
DE
245/* Return true if LIST has exactly one entry. */
246
247int
248one_inferior_p (struct inferior_list *list)
249{
250 return list->head != NULL && list->head == list->tail;
251}
252
253/* Reset head,tail of LIST, assuming all entries have already been freed. */
254
255void
256clear_inferior_list (struct inferior_list *list)
257{
258 list->head = NULL;
259 list->tail = NULL;
260}
255e7678
DJ
261
262void
263clear_inferiors (void)
264{
265 for_each_inferior (&all_threads, free_one_thread);
649ebbca 266 clear_inferior_list (&all_threads);
bf4c19f7
YQ
267
268 clear_dlls ();
7284e1be 269
0bfdf32f 270 current_thread = NULL;
255e7678 271}
24a09b5f 272
95954743
PA
273struct process_info *
274add_process (int pid, int attached)
275{
276 struct process_info *process;
277
278 process = xcalloc (1, sizeof (*process));
279
80894984 280 process->entry.id = pid_to_ptid (pid);
95954743
PA
281 process->attached = attached;
282
80894984 283 add_inferior_to_list (&all_processes, &process->entry);
95954743
PA
284
285 return process;
286}
287
5091eb23
DE
288/* Remove a process from the common process list and free the memory
289 allocated for it.
290 The caller is responsible for freeing private data first. */
291
95954743
PA
292void
293remove_process (struct process_info *process)
294{
295 clear_symbol_cache (&process->symbol_cache);
296 free_all_breakpoints (process);
80894984 297 remove_inferior (&all_processes, &process->entry);
5091eb23 298 free (process);
95954743
PA
299}
300
301struct process_info *
302find_process_pid (int pid)
303{
304 return (struct process_info *)
305 find_inferior_id (&all_processes, pid_to_ptid (pid));
306}
307
9f767825
DE
308/* Return non-zero if INF, a struct process_info, was started by us,
309 i.e. not attached to. */
310
311static int
312started_inferior_callback (struct inferior_list_entry *entry, void *args)
313{
314 struct process_info *process = (struct process_info *) entry;
315
316 return ! process->attached;
317}
318
319/* Return non-zero if there are any inferiors that we have created
320 (as opposed to attached-to). */
321
322int
323have_started_inferiors_p (void)
324{
325 return (find_inferior (&all_processes, started_inferior_callback, NULL)
326 != NULL);
327}
328
329/* Return non-zero if INF, a struct process_info, was attached to. */
330
331static int
332attached_inferior_callback (struct inferior_list_entry *entry, void *args)
333{
334 struct process_info *process = (struct process_info *) entry;
335
336 return process->attached;
337}
338
339/* Return non-zero if there are any inferiors that we have attached to. */
340
341int
342have_attached_inferiors_p (void)
343{
344 return (find_inferior (&all_processes, attached_inferior_callback, NULL)
345 != NULL);
346}
347
7fe519cb 348struct process_info *
95954743
PA
349get_thread_process (struct thread_info *thread)
350{
351 int pid = ptid_get_pid (thread->entry.id);
352 return find_process_pid (pid);
353}
354
355struct process_info *
356current_process (void)
357{
0bfdf32f
GB
358 gdb_assert (current_thread != NULL);
359 return get_thread_process (current_thread);
95954743 360}
This page took 1.010477 seconds and 4 git commands to generate.