1 /* Inferior process information for the remote server for GDB.
2 Copyright (C) 2002-2024 Free Software Foundation, Inc.
4 Contributed by MontaVista Software.
6 This file is part of GDB.
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.
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.
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/>. */
21 #include "gdbsupport/common-gdbthread.h"
22 #include "gdbsupport/common-inferior.h"
23 #include "gdbsupport/owning_intrusive_list.h"
24 #include "gdbthread.h"
27 owning_intrusive_list
<process_info
> all_processes
;
29 /* The current process. */
30 static process_info
*current_process_
;
32 /* The current thread. This is either a thread of CURRENT_PROCESS, or
34 thread_info
*current_thread
;
36 /* The current working directory used to start the inferior.
38 Empty if not specified. */
39 static std::string current_inferior_cwd
;
42 process_info::add_thread (ptid_t id
, void *target_data
)
44 auto &new_thread
= m_thread_list
.emplace_back (id
, this, target_data
);
45 bool inserted
= m_ptid_thread_map
.insert ({ id
, &new_thread
}).second
;
47 /* A thread with this ptid should not exist in the map yet. */
48 gdb_assert (inserted
);
50 if (current_thread
== NULL
)
51 switch_to_thread (&new_thread
);
56 /* See gdbthread.h. */
59 get_first_thread (void)
61 return find_thread ([] (thread_info
*thread
)
68 find_thread_ptid (ptid_t ptid
)
70 process_info
*process
= find_process_pid (ptid
.pid ());
71 if (process
== nullptr)
74 return process
->find_thread (ptid
);
77 /* Find a thread associated with the given PROCESS, or NULL if no
78 such thread exists. */
81 find_thread_process (const struct process_info
*const process
)
83 return find_any_thread_of_pid (process
->pid
);
86 /* See gdbthread.h. */
89 find_any_thread_of_pid (int pid
)
91 return find_thread (pid
, [] (thread_info
*thread
) {
97 process_info::remove_thread (thread_info
*thread
)
99 if (thread
->btrace
!= NULL
)
100 target_disable_btrace (thread
->btrace
);
102 discard_queued_stop_replies (thread
->id
);
104 if (current_thread
== thread
)
105 switch_to_thread (nullptr);
107 /* We should not try to remove a thread that was not added. */
108 gdb_assert (thread
->process () == this);
109 int num_erased
= m_ptid_thread_map
.erase (thread
->id
);
110 gdb_assert (num_erased
> 0);
112 m_thread_list
.erase (m_thread_list
.iterator_to (*thread
));
115 struct process_info
*
116 add_process (int pid
, int attached
)
118 return &all_processes
.emplace_back (pid
, attached
);
121 /* Remove a process from the common process list and free the memory
123 The caller is responsible for freeing private data first. */
126 remove_process (struct process_info
*process
)
128 clear_symbol_cache (&process
->symbol_cache
);
129 free_all_breakpoints (process
);
130 gdb_assert (find_thread_process (process
) == NULL
);
131 if (current_process () == process
)
132 switch_to_process (nullptr);
134 all_processes
.erase (all_processes
.iterator_to (*process
));
138 find_process_pid (int pid
)
140 return find_process ([&] (process_info
*process
) {
141 return process
->pid
== pid
;
145 /* Get the first process in the process list, or NULL if the list is empty. */
148 get_first_process (void)
150 if (!all_processes
.empty ())
151 return &all_processes
.front ();
156 /* Return non-zero if there are any inferiors that we have created
157 (as opposed to attached-to). */
160 have_started_inferiors_p (void)
162 return find_process ([] (process_info
*process
) {
163 return !process
->attached
;
167 /* Return non-zero if there are any inferiors that we have attached to. */
170 have_attached_inferiors_p (void)
172 return find_process ([] (process_info
*process
) {
173 return process
->attached
;
177 struct process_info
*
178 current_process (void)
180 return current_process_
;
183 /* See inferiors.h. */
186 for_each_process (gdb::function_view
<void (process_info
*)> func
)
188 owning_intrusive_list
<process_info
>::iterator next
, cur
189 = all_processes
.begin ();
191 while (cur
!= all_processes
.end ())
200 /* See inferiors.h. */
203 find_process (gdb::function_view
<bool (process_info
*)> func
)
205 for (process_info
&process
: all_processes
)
212 /* See inferiors.h. */
215 process_info::find_thread (ptid_t ptid
)
217 if (auto it
= m_ptid_thread_map
.find (ptid
);
218 it
!= m_ptid_thread_map
.end ())
224 /* See inferiors.h. */
227 process_info::find_thread (gdb::function_view
<bool (thread_info
*)> func
)
229 for (thread_info
&thread
: m_thread_list
)
236 /* See gdbthread.h. */
239 find_thread (gdb::function_view
<bool (thread_info
*)> func
)
241 for (process_info
&process
: all_processes
)
242 if (thread_info
*thread
= process
.find_thread (func
);
249 /* See gdbthread.h. */
252 find_thread (int pid
, gdb::function_view
<bool (thread_info
*)> func
)
254 process_info
*process
= find_process_pid (pid
);
255 if (process
== nullptr)
258 return process
->find_thread (func
);
261 /* See gdbthread.h. */
264 find_thread (ptid_t filter
, gdb::function_view
<bool (thread_info
*)> func
)
266 if (filter
== minus_one_ptid
)
267 return find_thread (func
);
269 process_info
*process
= find_process_pid (filter
.pid ());
270 if (process
== nullptr)
273 if (filter
.is_pid ())
274 return process
->find_thread (func
);
276 if (thread_info
*thread
= process
->find_thread (filter
);
277 thread
!= nullptr && func (thread
))
283 /* See gdbthread.h. */
286 for_each_thread (gdb::function_view
<void (thread_info
*)> func
)
288 for_each_process ([&] (process_info
*proc
)
290 proc
->for_each_thread (func
);
294 /* See inferiors.h. */
297 process_info::for_each_thread (gdb::function_view
<void (thread_info
*)> func
)
299 owning_intrusive_list
<thread_info
>::iterator next
, cur
300 = m_thread_list
.begin ();
302 while (cur
!= m_thread_list
.end ())
304 /* FUNC may alter the current iterator. */
312 /* See gdbthread.h. */
315 for_each_thread (ptid_t ptid
, gdb::function_view
<void (thread_info
*)> func
)
317 if (ptid
== minus_one_ptid
)
318 for_each_thread (func
);
319 else if (ptid
.is_pid ())
321 process_info
*process
= find_process_pid (ptid
.pid ());
323 if (process
!= nullptr)
324 process
->for_each_thread (func
);
327 find_thread (ptid
, [func
] (thread_info
*thread
)
334 /* See gdbthread.h. */
337 find_thread_in_random (ptid_t ptid
,
338 gdb::function_view
<bool (thread_info
*)> func
)
343 /* First count how many interesting entries we have. */
344 for_each_thread (ptid
, [&] (thread_info
*thread
)
353 /* Now randomly pick an entry out of those. */
354 random_selector
= (int)
355 ((count
* (double) rand ()) / (RAND_MAX
+ 1.0));
357 thread_info
*thread
= find_thread (ptid
, [&] (thread_info
*thr_arg
)
359 return func (thr_arg
) && (random_selector
-- == 0);
362 gdb_assert (thread
!= NULL
);
367 /* See gdbthread.h. */
370 find_thread_in_random (gdb::function_view
<bool (thread_info
*)> func
)
372 return find_thread_in_random (minus_one_ptid
, func
);
375 /* See gdbsupport/common-gdbthread.h. */
378 switch_to_thread (process_stratum_target
*ops
, ptid_t ptid
)
380 gdb_assert (ptid
!= minus_one_ptid
);
381 switch_to_thread (find_thread_ptid (ptid
));
384 /* See gdbthread.h. */
387 switch_to_thread (thread_info
*thread
)
389 if (thread
!= nullptr)
390 current_process_
= thread
->process ();
392 current_process_
= nullptr;
393 current_thread
= thread
;
396 /* See inferiors.h. */
399 switch_to_process (process_info
*proc
)
401 current_process_
= proc
;
402 current_thread
= nullptr;
405 /* See gdbsupport/common-inferior.h. */
410 return current_inferior_cwd
;
413 /* See inferiors.h. */
416 set_inferior_cwd (std::string cwd
)
418 current_inferior_cwd
= std::move (cwd
);
421 scoped_restore_current_thread::scoped_restore_current_thread ()
423 m_process
= current_process_
;
424 m_thread
= current_thread
;
427 scoped_restore_current_thread::~scoped_restore_current_thread ()
432 if (m_thread
!= nullptr)
433 switch_to_thread (m_thread
);
435 switch_to_process (m_process
);