GDBserver
inferiors.c
Go to the documentation of this file.
1 /* Inferior process information for the remote server for GDB.
2  Copyright (C) 2002-2015 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 
27 
29 
30 #define get_thread(inf) ((struct thread_info *)(inf))
31 
32 void
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 
44 /* Invoke ACTION for each inferior in LIST. */
45 
46 void
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 }
59 
60 /* Invoke ACTION for each inferior in LIST, passing DATA to ACTION. */
61 
62 void
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 
78 void
80  struct inferior_list_entry *entry)
81 {
82  struct inferior_list_entry **cur;
83 
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;
98 
99  (*cur)->next = entry->next;
100 
101  if (list->tail == entry)
102  list->tail = *cur;
103 }
104 
105 struct thread_info *
106 add_thread (ptid_t thread_id, void *target_data)
107 {
108  struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
109 
110  memset (new_thread, 0, sizeof (*new_thread));
111 
112  new_thread->entry.id = thread_id;
113  new_thread->last_resume_kind = resume_continue;
114  new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
115 
116  add_inferior_to_list (&all_threads, &new_thread->entry);
117 
118  if (current_thread == NULL)
119  current_thread = new_thread;
120 
121  new_thread->target_data = target_data;
122 
123  return new_thread;
124 }
125 
126 ptid_t
128 {
129  return thread->entry.id;
130 }
131 
132 /* Wrapper around get_first_inferior to return a struct thread_info *. */
133 
134 struct thread_info *
136 {
137  return (struct thread_info *) get_first_inferior (&all_threads);
138 }
139 
140 struct thread_info *
142 {
143  return (struct thread_info *) find_inferior_id (&all_threads, ptid);
144 }
145 
146 ptid_t
148 {
149  struct thread_info *thread = find_thread_ptid (gdb_id);
150 
151  return thread ? thread->entry.id : null_ptid;
152 }
153 
154 static void
156 {
157  struct thread_info *thread = get_thread (inf);
159  free (thread);
160 }
161 
162 void
163 remove_thread (struct thread_info *thread)
164 {
165  if (thread->btrace != NULL)
166  target_disable_btrace (thread->btrace);
167 
168  remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
169  free_one_thread (&thread->entry);
170 }
171 
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 
176 struct inferior_list_entry *
178 {
179  if (list->head != NULL)
180  return list->head;
181  return NULL;
182 }
183 
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 
187 struct inferior_list_entry *
189  int (*func) (struct inferior_list_entry *, void *), void *arg)
190 {
191  struct inferior_list_entry *inf = list->head;
192 
193  while (inf != NULL)
194  {
195  struct inferior_list_entry *next;
196 
197  next = inf->next;
198  if ((*func) (inf, arg))
199  return inf;
200  inf = next;
201  }
202 
203  return NULL;
204 }
205 
206 struct inferior_list_entry *
208 {
209  struct inferior_list_entry *inf = list->head;
210 
211  while (inf != NULL)
212  {
213  if (ptid_equal (inf->id, id))
214  return inf;
215  inf = inf->next;
216  }
217 
218  return NULL;
219 }
220 
221 void *
223 {
224  return inferior->target_data;
225 }
226 
227 void
228 set_inferior_target_data (struct thread_info *inferior, void *data)
229 {
230  inferior->target_data = data;
231 }
232 
233 void *
235 {
236  return inferior->regcache_data;
237 }
238 
239 void
240 set_inferior_regcache_data (struct thread_info *inferior, void *data)
241 {
242  inferior->regcache_data = data;
243 }
244 
245 /* Return true if LIST has exactly one entry. */
246 
247 int
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 
255 void
257 {
258  list->head = NULL;
259  list->tail = NULL;
260 }
261 
262 void
264 {
267 
268  clear_dlls ();
269 
270  current_thread = NULL;
271 }
272 
273 struct process_info *
274 add_process (int pid, int attached)
275 {
276  struct process_info *process;
277 
278  process = xcalloc (1, sizeof (*process));
279 
280  process->entry.id = pid_to_ptid (pid);
281  process->attached = attached;
282 
284 
285  return process;
286 }
287 
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 
292 void
293 remove_process (struct process_info *process)
294 {
295  clear_symbol_cache (&process->symbol_cache);
296  free_all_breakpoints (process);
297  remove_inferior (&all_processes, &process->entry);
298  free (process);
299 }
300 
301 struct process_info *
303 {
304  return (struct process_info *)
306 }
307 
308 /* Return non-zero if INF, a struct process_info, was started by us,
309  i.e. not attached to. */
310 
311 static int
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 
322 int
324 {
326  != NULL);
327 }
328 
329 /* Return non-zero if INF, a struct process_info, was attached to. */
330 
331 static int
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 
341 int
343 {
345  != NULL);
346 }
347 
348 struct process_info *
350 {
351  int pid = ptid_get_pid (thread->entry.id);
352  return find_process_pid (pid);
353 }
354 
355 struct process_info *
357 {
358  gdb_assert (current_thread != NULL);
359  return get_thread_process (current_thread);
360 }
struct thread_info * current_thread
Definition: inferiors.c:28
struct process_info * add_process(int pid, int attached)
Definition: inferiors.c:274
struct inferior_list all_threads
Definition: inferiors.c:26
struct btrace_target_info * btrace
Definition: gdbthread.h:70
void for_each_inferior_with_data(struct inferior_list *list, void(*action)(struct inferior_list_entry *, void *), void *data)
Definition: inferiors.c:63
struct thread_info * add_thread(ptid_t thread_id, void *target_data)
Definition: inferiors.c:106
void clear_symbol_cache(struct sym_cache **symcache_p)
int ptid_equal(ptid_t ptid1, ptid_t ptid2)
Definition: ptid.c:76
void * regcache_data
Definition: gdbthread.h:33
struct thread_info * get_first_thread(void)
Definition: inferiors.c:135
struct inferior_list_entry entry
Definition: inferiors.h:47
void set_inferior_regcache_data(struct thread_info *inferior, void *data)
Definition: inferiors.c:240
void clear_dlls(void)
Definition: dll.c:110
struct process_info * get_thread_process(struct thread_info *thread)
Definition: inferiors.c:349
struct process_info * find_process_pid(int pid)
Definition: inferiors.c:302
void for_each_inferior(struct inferior_list *list, void(*action)(struct inferior_list_entry *))
Definition: inferiors.c:47
ptid_t id
Definition: inferiors.h:31
void free_all_breakpoints(struct process_info *proc)
Definition: mem-break.c:1921
int have_attached_inferiors_p(void)
Definition: inferiors.c:342
int attached
Definition: inferiors.h:51
Definition: ptid.h:35
enum resume_kind last_resume_kind
Definition: gdbthread.h:36
struct inferior_list_entry entry
Definition: gdbthread.h:30
void * inferior_target_data(struct thread_info *inferior)
Definition: inferiors.c:222
void add_inferior_to_list(struct inferior_list *list, struct inferior_list_entry *new_inferior)
Definition: inferiors.c:33
void remove_inferior(struct inferior_list *list, struct inferior_list_entry *entry)
Definition: inferiors.c:79
void set_inferior_target_data(struct thread_info *inferior, void *data)
Definition: inferiors.c:228
void * target_data
Definition: gdbthread.h:32
ptid_t pid_to_ptid(int pid)
Definition: ptid.c:44
ptid_t thread_to_gdb_id(struct thread_info *thread)
Definition: inferiors.c:127
static void free_one_thread(struct inferior_list_entry *inf)
Definition: inferiors.c:155
struct inferior_list_entry * tail
Definition: inferiors.h:27
#define gdb_assert(expr)
Definition: gdb_assert.h:33
void remove_process(struct process_info *process)
Definition: inferiors.c:293
static int attached_inferior_callback(struct inferior_list_entry *entry, void *args)
Definition: inferiors.c:332
struct process_info * current_process(void)
Definition: inferiors.c:356
struct inferior_list_entry * head
Definition: inferiors.h:26
struct inferior_list all_processes
Definition: inferiors.c:25
ptid_t gdb_id_to_thread_id(ptid_t gdb_id)
Definition: inferiors.c:147
struct inferior_list_entry * find_inferior_id(struct inferior_list *list, ptid_t id)
Definition: inferiors.c:207
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
struct sym_cache * symbol_cache
Definition: inferiors.h:58
ptid_t null_ptid
Definition: ptid.c:25
void * inferior_regcache_data(struct thread_info *inferior)
Definition: inferiors.c:234
struct inferior_list_entry * next
Definition: inferiors.h:32
void remove_thread(struct thread_info *thread)
Definition: inferiors.c:163
int one_inferior_p(struct inferior_list *list)
Definition: inferiors.c:248
struct target_waitstatus last_status
Definition: gdbthread.h:39
int have_started_inferiors_p(void)
Definition: inferiors.c:323
struct inferior_list_entry * get_first_inferior(struct inferior_list *list)
Definition: inferiors.c:177
void free_register_cache(struct regcache *regcache)
Definition: regcache.c:171
PTR xmalloc(size_t size)
Definition: common-utils.c:34
Definition: inferiors.h:29
#define get_thread(inf)
Definition: inferiors.c:30
static int started_inferior_callback(struct inferior_list_entry *entry, void *args)
Definition: inferiors.c:312
struct thread_info * find_thread_ptid(ptid_t ptid)
Definition: inferiors.c:141
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:71
void clear_inferiors(void)
Definition: inferiors.c:263
void clear_inferior_list(struct inferior_list *list)
Definition: inferiors.c:256
struct inferior_list_entry * find_inferior(struct inferior_list *list, int(*func)(struct inferior_list_entry *, void *), void *arg)
Definition: inferiors.c:188
#define target_disable_btrace(tinfo)
Definition: target.h:577