1 /* Abstract base class inherited by all process_stratum targets
3 Copyright (C) 2018-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "process-stratum-target.h"
24 process_stratum_target::~process_stratum_target ()
29 process_stratum_target::thread_architecture (ptid_t ptid
)
31 inferior
*inf
= find_inferior_ptid (this, ptid
);
32 gdb_assert (inf
!= NULL
);
37 process_stratum_target::has_all_memory ()
39 /* If no inferior selected, then we can't read memory here. */
40 return inferior_ptid
!= null_ptid
;
44 process_stratum_target::has_memory ()
46 /* If no inferior selected, then we can't read memory here. */
47 return inferior_ptid
!= null_ptid
;
51 process_stratum_target::has_stack ()
53 /* If no inferior selected, there's no stack. */
54 return inferior_ptid
!= null_ptid
;
58 process_stratum_target::has_registers ()
60 /* Can't read registers from no inferior. */
61 return inferior_ptid
!= null_ptid
;
65 process_stratum_target::has_execution (inferior
*inf
)
67 /* If there's a process running already, we can't make it run
72 /* See process-stratum-target.h. */
75 process_stratum_target::follow_exec (inferior
*follow_inf
, ptid_t ptid
,
76 const char *execd_pathname
)
78 inferior
*orig_inf
= current_inferior ();
80 if (orig_inf
!= follow_inf
)
82 /* Execution continues in a new inferior, push the original inferior's
83 process target on the new inferior's target stack. The process target
84 may decide to unpush itself from the original inferior's target stack
85 after that, at its discretion. */
86 follow_inf
->push_target (orig_inf
->process_target ());
87 thread_info
*t
= add_thread (follow_inf
->process_target (), ptid
);
89 /* Leave the new inferior / thread as the current inferior / thread. */
94 /* See process-stratum-target.h. */
97 process_stratum_target::follow_fork (inferior
*child_inf
, ptid_t child_ptid
,
98 target_waitkind fork_kind
,
102 if (child_inf
!= nullptr)
104 child_inf
->push_target (this);
105 add_thread_silent (this, child_ptid
);
109 /* See process-stratum-target.h. */
112 process_stratum_target::maybe_add_resumed_with_pending_wait_status
113 (thread_info
*thread
)
115 gdb_assert (!thread
->resumed_with_pending_wait_status_node
.is_linked ());
117 if (thread
->resumed () && thread
->has_pending_waitstatus ())
119 infrun_debug_printf ("adding to resumed threads with event list: %s",
120 thread
->ptid
.to_string ().c_str ());
121 m_resumed_with_pending_wait_status
.push_back (*thread
);
125 /* See process-stratum-target.h. */
128 process_stratum_target::maybe_remove_resumed_with_pending_wait_status
129 (thread_info
*thread
)
131 if (thread
->resumed () && thread
->has_pending_waitstatus ())
133 infrun_debug_printf ("removing from resumed threads with event list: %s",
134 thread
->ptid
.to_string ().c_str ());
135 gdb_assert (thread
->resumed_with_pending_wait_status_node
.is_linked ());
136 auto it
= m_resumed_with_pending_wait_status
.iterator_to (*thread
);
137 m_resumed_with_pending_wait_status
.erase (it
);
140 gdb_assert (!thread
->resumed_with_pending_wait_status_node
.is_linked ());
143 /* See process-stratum-target.h. */
146 process_stratum_target::random_resumed_with_pending_wait_status
147 (inferior
*inf
, ptid_t filter_ptid
)
149 auto matches
= [inf
, filter_ptid
] (const thread_info
&thread
)
151 return thread
.inf
== inf
&& thread
.ptid
.matches (filter_ptid
);
154 /* First see how many matching events we have. */
155 const auto &l
= m_resumed_with_pending_wait_status
;
156 unsigned int count
= std::count_if (l
.begin (), l
.end (), matches
);
161 /* Now randomly pick a thread out of those that match the criteria. */
163 = (int) ((count
* (double) rand ()) / (RAND_MAX
+ 1.0));
166 infrun_debug_printf ("Found %u events, selecting #%d",
167 count
, random_selector
);
169 /* Select the Nth thread that matches. */
170 auto it
= std::find_if (l
.begin (), l
.end (),
171 [&random_selector
, &matches
]
172 (const thread_info
&thread
)
174 if (!matches (thread
))
177 return random_selector
-- == 0;
180 gdb_assert (it
!= l
.end ());
185 /* See process-stratum-target.h. */
188 process_stratum_target::find_thread (ptid_t ptid
)
190 inferior
*inf
= find_inferior_ptid (this, ptid
);
193 return inf
->find_thread (ptid
);
196 /* See process-stratum-target.h. */
198 std::set
<process_stratum_target
*>
199 all_non_exited_process_targets ()
201 /* Inferiors may share targets. To eliminate duplicates, use a set. */
202 std::set
<process_stratum_target
*> targets
;
203 for (inferior
*inf
: all_non_exited_inferiors ())
204 targets
.insert (inf
->process_target ());
209 /* See process-stratum-target.h. */
212 switch_to_target_no_thread (process_stratum_target
*target
)
214 for (inferior
*inf
: all_inferiors (target
))
216 switch_to_inferior_no_thread (inf
);