]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/process-stratum-target.c
internal_error: remove need to pass __FILE__/__LINE__
[thirdparty/binutils-gdb.git] / gdb / process-stratum-target.c
CommitLineData
3b3dac9b
PA
1/* Abstract base class inherited by all process_stratum targets
2
4a94e368 3 Copyright (C) 2018-2022 Free Software Foundation, Inc.
3b3dac9b
PA
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "process-stratum-target.h"
22#include "inferior.h"
71a23490 23#include <algorithm>
3b3dac9b
PA
24
25process_stratum_target::~process_stratum_target ()
26{
27}
28
29struct address_space *
30process_stratum_target::thread_address_space (ptid_t ptid)
31{
32 /* Fall-back to the "main" address space of the inferior. */
5b6d1e4f 33 inferior *inf = find_inferior_ptid (this, ptid);
3b3dac9b
PA
34
35 if (inf == NULL || inf->aspace == NULL)
f34652de 36 internal_error (_("Can't determine the current "
3b3dac9b 37 "address space of thread %s\n"),
a068643d 38 target_pid_to_str (ptid).c_str ());
3b3dac9b
PA
39
40 return inf->aspace;
41}
42
43struct gdbarch *
44process_stratum_target::thread_architecture (ptid_t ptid)
45{
5b6d1e4f 46 inferior *inf = find_inferior_ptid (this, ptid);
3b3dac9b
PA
47 gdb_assert (inf != NULL);
48 return inf->gdbarch;
49}
f3d11a9a
PA
50
51bool
52process_stratum_target::has_all_memory ()
53{
54 /* If no inferior selected, then we can't read memory here. */
55 return inferior_ptid != null_ptid;
56}
57
58bool
59process_stratum_target::has_memory ()
60{
61 /* If no inferior selected, then we can't read memory here. */
62 return inferior_ptid != null_ptid;
63}
64
65bool
66process_stratum_target::has_stack ()
67{
68 /* If no inferior selected, there's no stack. */
69 return inferior_ptid != null_ptid;
70}
71
72bool
73process_stratum_target::has_registers ()
74{
75 /* Can't read registers from no inferior. */
76 return inferior_ptid != null_ptid;
77}
78
79bool
5018ce90 80process_stratum_target::has_execution (inferior *inf)
f3d11a9a 81{
5018ce90
PA
82 /* If there's a process running already, we can't make it run
83 through hoops. */
84 return inf->pid != 0;
f3d11a9a 85}
d890404b 86
82d1f134
SM
87/* See process-stratum-target.h. */
88
294c36eb
SM
89void
90process_stratum_target::follow_exec (inferior *follow_inf, ptid_t ptid,
91 const char *execd_pathname)
92{
93 inferior *orig_inf = current_inferior ();
94
95 if (orig_inf != follow_inf)
96 {
97 /* Execution continues in a new inferior, push the original inferior's
98 process target on the new inferior's target stack. The process target
99 may decide to unpush itself from the original inferior's target stack
100 after that, at its discretion. */
101 follow_inf->push_target (orig_inf->process_target ());
102 thread_info *t = add_thread (follow_inf->process_target (), ptid);
103
104 /* Leave the new inferior / thread as the current inferior / thread. */
105 switch_to_thread (t);
106 }
107}
108
d890404b
TBA
109/* See process-stratum-target.h. */
110
82d1f134
SM
111void
112process_stratum_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
113 target_waitkind fork_kind,
114 bool follow_child,
115 bool detach_on_fork)
116{
117 if (child_inf != nullptr)
118 {
119 child_inf->push_target (this);
120 add_thread_silent (this, child_ptid);
121 }
122}
123
124/* See process-stratum-target.h. */
125
a66f7298
SM
126void
127process_stratum_target::maybe_add_resumed_with_pending_wait_status
128 (thread_info *thread)
129{
130 gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ());
131
132 if (thread->resumed () && thread->has_pending_waitstatus ())
133 {
134 infrun_debug_printf ("adding to resumed threads with event list: %s",
135 thread->ptid.to_string ().c_str ());
136 m_resumed_with_pending_wait_status.push_back (*thread);
137 }
138}
139
140/* See process-stratum-target.h. */
141
142void
143process_stratum_target::maybe_remove_resumed_with_pending_wait_status
144 (thread_info *thread)
145{
146 if (thread->resumed () && thread->has_pending_waitstatus ())
147 {
148 infrun_debug_printf ("removing from resumed threads with event list: %s",
149 thread->ptid.to_string ().c_str ());
150 gdb_assert (thread->resumed_with_pending_wait_status_node.is_linked ());
151 auto it = m_resumed_with_pending_wait_status.iterator_to (*thread);
152 m_resumed_with_pending_wait_status.erase (it);
153 }
154 else
155 gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ());
156}
157
158/* See process-stratum-target.h. */
159
71a23490
SM
160thread_info *
161process_stratum_target::random_resumed_with_pending_wait_status
162 (inferior *inf, ptid_t filter_ptid)
163{
164 auto matches = [inf, filter_ptid] (const thread_info &thread)
165 {
166 return thread.inf == inf && thread.ptid.matches (filter_ptid);
167 };
168
169 /* First see how many matching events we have. */
170 const auto &l = m_resumed_with_pending_wait_status;
171 unsigned int count = std::count_if (l.begin (), l.end (), matches);
172
173 if (count == 0)
174 return nullptr;
175
176 /* Now randomly pick a thread out of those that match the criteria. */
177 int random_selector
178 = (int) ((count * (double) rand ()) / (RAND_MAX + 1.0));
179
180 if (count > 1)
181 infrun_debug_printf ("Found %u events, selecting #%d",
182 count, random_selector);
183
184 /* Select the Nth thread that matches. */
185 auto it = std::find_if (l.begin (), l.end (),
186 [&random_selector, &matches]
187 (const thread_info &thread)
188 {
189 if (!matches (thread))
190 return false;
191
192 return random_selector-- == 0;
193 });
194
195 gdb_assert (it != l.end ());
196
197 return &*it;
198}
199
200/* See process-stratum-target.h. */
201
d890404b
TBA
202std::set<process_stratum_target *>
203all_non_exited_process_targets ()
204{
205 /* Inferiors may share targets. To eliminate duplicates, use a set. */
206 std::set<process_stratum_target *> targets;
207 for (inferior *inf : all_non_exited_inferiors ())
208 targets.insert (inf->process_target ());
209
210 return targets;
211}
212
213/* See process-stratum-target.h. */
214
215void
216switch_to_target_no_thread (process_stratum_target *target)
217{
218 for (inferior *inf : all_inferiors (target))
219 {
220 switch_to_inferior_no_thread (inf);
221 break;
222 }
223}