GDB (xrefs)
Loading...
Searching...
No Matches
process-stratum-target.c
Go to the documentation of this file.
1/* Abstract base class inherited by all process_stratum targets
2
3 Copyright (C) 2018-2023 Free Software Foundation, Inc.
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"
22#include "inferior.h"
23#include <algorithm>
24
28
29struct address_space *
31{
32 /* Fall-back to the "main" address space of the inferior. */
33 inferior *inf = find_inferior_ptid (this, ptid);
34
35 if (inf == NULL || inf->aspace == NULL)
36 internal_error (_("Can't determine the current "
37 "address space of thread %s\n"),
38 target_pid_to_str (ptid).c_str ());
39
40 return inf->aspace;
41}
42
43struct gdbarch *
45{
46 inferior *inf = find_inferior_ptid (this, ptid);
47 gdb_assert (inf != NULL);
48 return inf->gdbarch;
49}
50
51bool
53{
54 /* If no inferior selected, then we can't read memory here. */
55 return inferior_ptid != null_ptid;
56}
57
58bool
60{
61 /* If no inferior selected, then we can't read memory here. */
62 return inferior_ptid != null_ptid;
63}
64
65bool
67{
68 /* If no inferior selected, there's no stack. */
69 return inferior_ptid != null_ptid;
70}
71
72bool
74{
75 /* Can't read registers from no inferior. */
76 return inferior_ptid != null_ptid;
77}
78
79bool
81{
82 /* If there's a process running already, we can't make it run
83 through hoops. */
84 return inf->pid != 0;
85}
86
87/* See process-stratum-target.h. */
88
89void
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. */
106 }
107}
108
109/* See process-stratum-target.h. */
110
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
126void
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
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);
153 }
154 else
155 gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ());
156}
157
158/* See process-stratum-target.h. */
159
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. */
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
204{
205 inferior *inf = find_inferior_ptid (this, ptid);
206 if (inf == NULL)
207 return NULL;
208 return inf->find_thread (ptid);
209}
210
211/* See process-stratum-target.h. */
212
213std::set<process_stratum_target *>
215{
216 /* Inferiors may share targets. To eliminate duplicates, use a set. */
217 std::set<process_stratum_target *> targets;
219 targets.insert (inf->process_target ());
220
221 return targets;
222}
223
224/* See process-stratum-target.h. */
225
226void
228{
229 for (inferior *inf : all_inferiors (target))
230 {
232 break;
233 }
234}
void push_target(struct target_ops *t)
Definition inferior.h:406
struct process_stratum_target * process_target()
Definition inferior.h:449
void follow_fork(inferior *child_inf, ptid_t child_ptid, target_waitkind fork_kind, bool follow_child, bool detach_on_fork) override
struct gdbarch * thread_architecture(ptid_t ptid) override
thread_info * find_thread(ptid_t ptid)
thread_info_resumed_with_pending_wait_status_list m_resumed_with_pending_wait_status
void maybe_remove_resumed_with_pending_wait_status(thread_info *thread)
void follow_exec(inferior *follow_inf, ptid_t ptid, const char *execd_pathname) override
thread_info * random_resumed_with_pending_wait_status(inferior *inf, ptid_t filter_ptid)
struct address_space * thread_address_space(ptid_t ptid) override
bool has_execution(inferior *inf) override
void maybe_add_resumed_with_pending_wait_status(thread_info *thread)
intrusive_list_node< thread_info > resumed_with_pending_wait_status_node
Definition gdbthread.h:549
ptid_t ptid
Definition gdbthread.h:259
bool resumed() const
Definition gdbthread.h:326
bool has_pending_waitstatus() const
Definition gdbthread.h:394
struct inferior * inf
Definition gdbthread.h:301
struct thread_info * add_thread(process_stratum_target *targ, ptid_t ptid)
Definition thread.c:336
struct thread_info * add_thread_silent(process_stratum_target *targ, ptid_t ptid)
Definition thread.c:296
void switch_to_thread(struct thread_info *thr)
Definition thread.c:1360
ptid_t inferior_ptid
Definition infcmd.c:74
struct inferior * find_inferior_ptid(process_stratum_target *targ, ptid_t ptid)
Definition inferior.c:406
struct inferior * current_inferior(void)
Definition inferior.c:55
void switch_to_inferior_no_thread(inferior *inf)
Definition inferior.c:712
all_inferiors_range all_inferiors(process_stratum_target *proc_target=nullptr)
Definition inferior.h:821
all_non_exited_inferiors_range all_non_exited_inferiors(process_stratum_target *proc_target=nullptr)
Definition inferior.h:830
#define infrun_debug_printf(fmt,...)
Definition infrun.h:38
std::set< process_stratum_target * > all_non_exited_process_targets()
void switch_to_target_no_thread(process_stratum_target *target)
Definition gnu-nat.c:153
pid_t pid
Definition gnu-nat.c:165
std::string target_pid_to_str(ptid_t ptid)
Definition target.c:2623
target_waitkind
Definition waitstatus.h:30