gdb: fix vfork with multiple threads
[deliverable/binutils-gdb.git] / gdbserver / inferiors.cc
1 /* Inferior process information for the remote server for GDB.
2 Copyright (C) 2002-2021 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 "gdbsupport/common-inferior.h"
23 #include "gdbthread.h"
24 #include "dll.h"
25
26 std::list<process_info *> all_processes;
27 std::list<thread_info *> all_threads;
28
29 struct thread_info *current_thread;
30
31 /* The current working directory used to start the inferior. */
32 static const char *current_inferior_cwd = NULL;
33
34 struct thread_info *
35 add_thread (ptid_t thread_id, void *target_data)
36 {
37 thread_info *new_thread = new thread_info (thread_id, target_data);
38
39 all_threads.push_back (new_thread);
40
41 if (current_thread == NULL)
42 current_thread = new_thread;
43
44 return new_thread;
45 }
46
47 /* See gdbthread.h. */
48
49 struct thread_info *
50 get_first_thread (void)
51 {
52 if (!all_threads.empty ())
53 return all_threads.front ();
54 else
55 return NULL;
56 }
57
58 struct thread_info *
59 find_thread_ptid (ptid_t ptid)
60 {
61 return find_thread ([&] (thread_info *thread) {
62 return thread->id == ptid;
63 });
64 }
65
66 /* Find a thread associated with the given PROCESS, or NULL if no
67 such thread exists. */
68
69 static struct thread_info *
70 find_thread_process (const struct process_info *const process)
71 {
72 return find_any_thread_of_pid (process->pid);
73 }
74
75 /* See gdbthread.h. */
76
77 struct thread_info *
78 find_any_thread_of_pid (int pid)
79 {
80 return find_thread (pid, [] (thread_info *thread) {
81 return true;
82 });
83 }
84
85 static void
86 free_one_thread (thread_info *thread)
87 {
88 delete thread;
89 }
90
91 void
92 remove_thread (struct thread_info *thread)
93 {
94 if (thread->btrace != NULL)
95 target_disable_btrace (thread->btrace);
96
97 discard_queued_stop_replies (ptid_of (thread));
98 all_threads.remove (thread);
99 if (current_thread == thread)
100 current_thread = NULL;
101 free_one_thread (thread);
102 }
103
104 void *
105 thread_target_data (struct thread_info *thread)
106 {
107 return thread->target_data;
108 }
109
110 struct regcache *
111 thread_regcache_data (struct thread_info *thread)
112 {
113 return thread->regcache_data;
114 }
115
116 void
117 set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
118 {
119 thread->regcache_data = data;
120 }
121
122 void
123 clear_inferiors (void)
124 {
125 for_each_thread (free_one_thread);
126 all_threads.clear ();
127
128 clear_dlls ();
129
130 current_thread = NULL;
131 }
132
133 struct process_info *
134 add_process (int pid, int attached)
135 {
136 process_info *process = new process_info (pid, attached);
137
138 all_processes.push_back (process);
139
140 return process;
141 }
142
143 /* Remove a process from the common process list and free the memory
144 allocated for it.
145 The caller is responsible for freeing private data first. */
146
147 void
148 remove_process (struct process_info *process)
149 {
150 clear_symbol_cache (&process->symbol_cache);
151 free_all_breakpoints (process);
152 gdb_assert (find_thread_process (process) == NULL);
153 all_processes.remove (process);
154 delete process;
155 }
156
157 process_info *
158 find_process_pid (int pid)
159 {
160 return find_process ([&] (process_info *process) {
161 return process->pid == pid;
162 });
163 }
164
165 /* Get the first process in the process list, or NULL if the list is empty. */
166
167 process_info *
168 get_first_process (void)
169 {
170 if (!all_processes.empty ())
171 return all_processes.front ();
172 else
173 return NULL;
174 }
175
176 /* Return non-zero if there are any inferiors that we have created
177 (as opposed to attached-to). */
178
179 int
180 have_started_inferiors_p (void)
181 {
182 return find_process ([] (process_info *process) {
183 return !process->attached;
184 }) != NULL;
185 }
186
187 /* Return non-zero if there are any inferiors that we have attached to. */
188
189 int
190 have_attached_inferiors_p (void)
191 {
192 return find_process ([] (process_info *process) {
193 return process->attached;
194 }) != NULL;
195 }
196
197 struct process_info *
198 get_thread_process (const struct thread_info *thread)
199 {
200 return find_process_pid (thread->id.pid ());
201 }
202
203 struct process_info *
204 current_process (void)
205 {
206 gdb_assert (current_thread != NULL);
207 return get_thread_process (current_thread);
208 }
209
210 /* See gdbsupport/common-gdbthread.h. */
211
212 void
213 switch_to_thread (process_stratum_target *ops, ptid_t ptid)
214 {
215 gdb_assert (ptid != minus_one_ptid);
216 current_thread = find_thread_ptid (ptid);
217 }
218
219 /* See inferiors.h. */
220
221 void
222 switch_to_process (process_info *proc)
223 {
224 int pid = pid_of (proc);
225
226 current_thread = find_any_thread_of_pid (pid);
227 }
228
229 /* See gdbsupport/common-inferior.h. */
230
231 const char *
232 get_inferior_cwd ()
233 {
234 return current_inferior_cwd;
235 }
236
237 /* See gdbsupport/common-inferior.h. */
238
239 void
240 set_inferior_cwd (const char *cwd)
241 {
242 xfree ((void *) current_inferior_cwd);
243 if (cwd != NULL)
244 current_inferior_cwd = xstrdup (cwd);
245 else
246 current_inferior_cwd = NULL;
247 }
This page took 0.03434 seconds and 4 git commands to generate.