Make process_info::syscalls_to_catch an std::vector
[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 /* See gdbthread.h. */
136
137 struct thread_info *
138 find_any_thread_of_pid (int pid)
139 {
140 return find_thread (pid, [] (thread_info *thread) {
141 return true;
142 });
143 }
144
145 static void
146 free_one_thread (thread_info *thread)
147 {
148 free_register_cache (thread_regcache_data (thread));
149 free (thread);
150 }
151
152 void
153 remove_thread (struct thread_info *thread)
154 {
155 if (thread->btrace != NULL)
156 target_disable_btrace (thread->btrace);
157
158 discard_queued_stop_replies (ptid_of (thread));
159 all_threads.remove (thread);
160 free_one_thread (thread);
161 if (current_thread == thread)
162 current_thread = NULL;
163 }
164
165 void *
166 thread_target_data (struct thread_info *thread)
167 {
168 return thread->target_data;
169 }
170
171 struct regcache *
172 thread_regcache_data (struct thread_info *thread)
173 {
174 return thread->regcache_data;
175 }
176
177 void
178 set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
179 {
180 thread->regcache_data = data;
181 }
182
183 void
184 clear_inferiors (void)
185 {
186 for_each_inferior (&all_threads, free_one_thread);
187 all_threads.clear ();
188
189 clear_dlls ();
190
191 current_thread = NULL;
192 }
193
194 struct process_info *
195 add_process (int pid, int attached)
196 {
197 process_info *process = new process_info (pid, attached);
198
199 all_processes.push_back (process);
200
201 return process;
202 }
203
204 /* Remove a process from the common process list and free the memory
205 allocated for it.
206 The caller is responsible for freeing private data first. */
207
208 void
209 remove_process (struct process_info *process)
210 {
211 clear_symbol_cache (&process->symbol_cache);
212 free_all_breakpoints (process);
213 gdb_assert (find_thread_process (process) == NULL);
214 all_processes.remove (process);
215 delete process;
216 }
217
218 process_info *
219 find_process_pid (int pid)
220 {
221 return find_process ([&] (process_info *process) {
222 return process->pid == pid;
223 });
224 }
225
226 /* Get the first process in the process list, or NULL if the list is empty. */
227
228 process_info *
229 get_first_process (void)
230 {
231 if (!all_processes.empty ())
232 return all_processes.front ();
233 else
234 return NULL;
235 }
236
237 /* Return non-zero if there are any inferiors that we have created
238 (as opposed to attached-to). */
239
240 int
241 have_started_inferiors_p (void)
242 {
243 return find_process ([] (process_info *process) {
244 return !process->attached;
245 }) != NULL;
246 }
247
248 /* Return non-zero if there are any inferiors that we have attached to. */
249
250 int
251 have_attached_inferiors_p (void)
252 {
253 return find_process ([] (process_info *process) {
254 return process->attached;
255 }) != NULL;
256 }
257
258 struct process_info *
259 get_thread_process (const struct thread_info *thread)
260 {
261 return find_process_pid (thread->id.pid ());
262 }
263
264 struct process_info *
265 current_process (void)
266 {
267 gdb_assert (current_thread != NULL);
268 return get_thread_process (current_thread);
269 }
270
271 static void
272 do_restore_current_thread_cleanup (void *arg)
273 {
274 current_thread = (struct thread_info *) arg;
275 }
276
277 struct cleanup *
278 make_cleanup_restore_current_thread (void)
279 {
280 return make_cleanup (do_restore_current_thread_cleanup, current_thread);
281 }
282
283 /* See common/common-gdbthread.h. */
284
285 void
286 switch_to_thread (ptid_t ptid)
287 {
288 gdb_assert (ptid != minus_one_ptid);
289 current_thread = find_thread_ptid (ptid);
290 }
291
292 /* See common/common-inferior.h. */
293
294 const char *
295 get_inferior_cwd ()
296 {
297 return current_inferior_cwd;
298 }
299
300 /* See common/common-inferior.h. */
301
302 void
303 set_inferior_cwd (const char *cwd)
304 {
305 xfree ((void *) current_inferior_cwd);
306 if (cwd != NULL)
307 current_inferior_cwd = xstrdup (cwd);
308 else
309 current_inferior_cwd = NULL;
310 }
This page took 0.042466 seconds and 5 git commands to generate.