17f2ac410Schristos /* Abstract base class inherited by all process_stratum targets 27f2ac410Schristos 3*6881a400Schristos Copyright (C) 2018-2023 Free Software Foundation, Inc. 47f2ac410Schristos 57f2ac410Schristos This file is part of GDB. 67f2ac410Schristos 77f2ac410Schristos This program is free software; you can redistribute it and/or modify 87f2ac410Schristos it under the terms of the GNU General Public License as published by 97f2ac410Schristos the Free Software Foundation; either version 3 of the License, or 107f2ac410Schristos (at your option) any later version. 117f2ac410Schristos 127f2ac410Schristos This program is distributed in the hope that it will be useful, 137f2ac410Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147f2ac410Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157f2ac410Schristos GNU General Public License for more details. 167f2ac410Schristos 177f2ac410Schristos You should have received a copy of the GNU General Public License 187f2ac410Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197f2ac410Schristos 207f2ac410Schristos #include "defs.h" 217f2ac410Schristos #include "process-stratum-target.h" 227f2ac410Schristos #include "inferior.h" 23*6881a400Schristos #include <algorithm> 247f2ac410Schristos 257f2ac410Schristos process_stratum_target::~process_stratum_target () 267f2ac410Schristos { 277f2ac410Schristos } 287f2ac410Schristos 297f2ac410Schristos struct address_space * 307f2ac410Schristos process_stratum_target::thread_address_space (ptid_t ptid) 317f2ac410Schristos { 327f2ac410Schristos /* Fall-back to the "main" address space of the inferior. */ 337d62b00eSchristos inferior *inf = find_inferior_ptid (this, ptid); 347f2ac410Schristos 357f2ac410Schristos if (inf == NULL || inf->aspace == NULL) 36*6881a400Schristos internal_error (_("Can't determine the current " 377f2ac410Schristos "address space of thread %s\n"), 387d62b00eSchristos target_pid_to_str (ptid).c_str ()); 397f2ac410Schristos 407f2ac410Schristos return inf->aspace; 417f2ac410Schristos } 427f2ac410Schristos 437f2ac410Schristos struct gdbarch * 447f2ac410Schristos process_stratum_target::thread_architecture (ptid_t ptid) 457f2ac410Schristos { 467d62b00eSchristos inferior *inf = find_inferior_ptid (this, ptid); 477f2ac410Schristos gdb_assert (inf != NULL); 487f2ac410Schristos return inf->gdbarch; 497f2ac410Schristos } 507f2ac410Schristos 517f2ac410Schristos bool 527f2ac410Schristos process_stratum_target::has_all_memory () 537f2ac410Schristos { 547f2ac410Schristos /* If no inferior selected, then we can't read memory here. */ 557f2ac410Schristos return inferior_ptid != null_ptid; 567f2ac410Schristos } 577f2ac410Schristos 587f2ac410Schristos bool 597f2ac410Schristos process_stratum_target::has_memory () 607f2ac410Schristos { 617f2ac410Schristos /* If no inferior selected, then we can't read memory here. */ 627f2ac410Schristos return inferior_ptid != null_ptid; 637f2ac410Schristos } 647f2ac410Schristos 657f2ac410Schristos bool 667f2ac410Schristos process_stratum_target::has_stack () 677f2ac410Schristos { 687f2ac410Schristos /* If no inferior selected, there's no stack. */ 697f2ac410Schristos return inferior_ptid != null_ptid; 707f2ac410Schristos } 717f2ac410Schristos 727f2ac410Schristos bool 737f2ac410Schristos process_stratum_target::has_registers () 747f2ac410Schristos { 757f2ac410Schristos /* Can't read registers from no inferior. */ 767f2ac410Schristos return inferior_ptid != null_ptid; 777f2ac410Schristos } 787f2ac410Schristos 797f2ac410Schristos bool 807d62b00eSchristos process_stratum_target::has_execution (inferior *inf) 817f2ac410Schristos { 827d62b00eSchristos /* If there's a process running already, we can't make it run 837d62b00eSchristos through hoops. */ 847d62b00eSchristos return inf->pid != 0; 857d62b00eSchristos } 867d62b00eSchristos 877d62b00eSchristos /* See process-stratum-target.h. */ 887d62b00eSchristos 89*6881a400Schristos void 90*6881a400Schristos process_stratum_target::follow_exec (inferior *follow_inf, ptid_t ptid, 91*6881a400Schristos const char *execd_pathname) 92*6881a400Schristos { 93*6881a400Schristos inferior *orig_inf = current_inferior (); 94*6881a400Schristos 95*6881a400Schristos if (orig_inf != follow_inf) 96*6881a400Schristos { 97*6881a400Schristos /* Execution continues in a new inferior, push the original inferior's 98*6881a400Schristos process target on the new inferior's target stack. The process target 99*6881a400Schristos may decide to unpush itself from the original inferior's target stack 100*6881a400Schristos after that, at its discretion. */ 101*6881a400Schristos follow_inf->push_target (orig_inf->process_target ()); 102*6881a400Schristos thread_info *t = add_thread (follow_inf->process_target (), ptid); 103*6881a400Schristos 104*6881a400Schristos /* Leave the new inferior / thread as the current inferior / thread. */ 105*6881a400Schristos switch_to_thread (t); 106*6881a400Schristos } 107*6881a400Schristos } 108*6881a400Schristos 109*6881a400Schristos /* See process-stratum-target.h. */ 110*6881a400Schristos 111*6881a400Schristos void 112*6881a400Schristos process_stratum_target::follow_fork (inferior *child_inf, ptid_t child_ptid, 113*6881a400Schristos target_waitkind fork_kind, 114*6881a400Schristos bool follow_child, 115*6881a400Schristos bool detach_on_fork) 116*6881a400Schristos { 117*6881a400Schristos if (child_inf != nullptr) 118*6881a400Schristos { 119*6881a400Schristos child_inf->push_target (this); 120*6881a400Schristos add_thread_silent (this, child_ptid); 121*6881a400Schristos } 122*6881a400Schristos } 123*6881a400Schristos 124*6881a400Schristos /* See process-stratum-target.h. */ 125*6881a400Schristos 126*6881a400Schristos void 127*6881a400Schristos process_stratum_target::maybe_add_resumed_with_pending_wait_status 128*6881a400Schristos (thread_info *thread) 129*6881a400Schristos { 130*6881a400Schristos gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ()); 131*6881a400Schristos 132*6881a400Schristos if (thread->resumed () && thread->has_pending_waitstatus ()) 133*6881a400Schristos { 134*6881a400Schristos infrun_debug_printf ("adding to resumed threads with event list: %s", 135*6881a400Schristos thread->ptid.to_string ().c_str ()); 136*6881a400Schristos m_resumed_with_pending_wait_status.push_back (*thread); 137*6881a400Schristos } 138*6881a400Schristos } 139*6881a400Schristos 140*6881a400Schristos /* See process-stratum-target.h. */ 141*6881a400Schristos 142*6881a400Schristos void 143*6881a400Schristos process_stratum_target::maybe_remove_resumed_with_pending_wait_status 144*6881a400Schristos (thread_info *thread) 145*6881a400Schristos { 146*6881a400Schristos if (thread->resumed () && thread->has_pending_waitstatus ()) 147*6881a400Schristos { 148*6881a400Schristos infrun_debug_printf ("removing from resumed threads with event list: %s", 149*6881a400Schristos thread->ptid.to_string ().c_str ()); 150*6881a400Schristos gdb_assert (thread->resumed_with_pending_wait_status_node.is_linked ()); 151*6881a400Schristos auto it = m_resumed_with_pending_wait_status.iterator_to (*thread); 152*6881a400Schristos m_resumed_with_pending_wait_status.erase (it); 153*6881a400Schristos } 154*6881a400Schristos else 155*6881a400Schristos gdb_assert (!thread->resumed_with_pending_wait_status_node.is_linked ()); 156*6881a400Schristos } 157*6881a400Schristos 158*6881a400Schristos /* See process-stratum-target.h. */ 159*6881a400Schristos 160*6881a400Schristos thread_info * 161*6881a400Schristos process_stratum_target::random_resumed_with_pending_wait_status 162*6881a400Schristos (inferior *inf, ptid_t filter_ptid) 163*6881a400Schristos { 164*6881a400Schristos auto matches = [inf, filter_ptid] (const thread_info &thread) 165*6881a400Schristos { 166*6881a400Schristos return thread.inf == inf && thread.ptid.matches (filter_ptid); 167*6881a400Schristos }; 168*6881a400Schristos 169*6881a400Schristos /* First see how many matching events we have. */ 170*6881a400Schristos const auto &l = m_resumed_with_pending_wait_status; 171*6881a400Schristos unsigned int count = std::count_if (l.begin (), l.end (), matches); 172*6881a400Schristos 173*6881a400Schristos if (count == 0) 174*6881a400Schristos return nullptr; 175*6881a400Schristos 176*6881a400Schristos /* Now randomly pick a thread out of those that match the criteria. */ 177*6881a400Schristos int random_selector 178*6881a400Schristos = (int) ((count * (double) rand ()) / (RAND_MAX + 1.0)); 179*6881a400Schristos 180*6881a400Schristos if (count > 1) 181*6881a400Schristos infrun_debug_printf ("Found %u events, selecting #%d", 182*6881a400Schristos count, random_selector); 183*6881a400Schristos 184*6881a400Schristos /* Select the Nth thread that matches. */ 185*6881a400Schristos auto it = std::find_if (l.begin (), l.end (), 186*6881a400Schristos [&random_selector, &matches] 187*6881a400Schristos (const thread_info &thread) 188*6881a400Schristos { 189*6881a400Schristos if (!matches (thread)) 190*6881a400Schristos return false; 191*6881a400Schristos 192*6881a400Schristos return random_selector-- == 0; 193*6881a400Schristos }); 194*6881a400Schristos 195*6881a400Schristos gdb_assert (it != l.end ()); 196*6881a400Schristos 197*6881a400Schristos return &*it; 198*6881a400Schristos } 199*6881a400Schristos 200*6881a400Schristos /* See process-stratum-target.h. */ 201*6881a400Schristos 2027d62b00eSchristos std::set<process_stratum_target *> 2037d62b00eSchristos all_non_exited_process_targets () 2047d62b00eSchristos { 2057d62b00eSchristos /* Inferiors may share targets. To eliminate duplicates, use a set. */ 2067d62b00eSchristos std::set<process_stratum_target *> targets; 2077d62b00eSchristos for (inferior *inf : all_non_exited_inferiors ()) 2087d62b00eSchristos targets.insert (inf->process_target ()); 2097d62b00eSchristos 2107d62b00eSchristos return targets; 2117d62b00eSchristos } 2127d62b00eSchristos 2137d62b00eSchristos /* See process-stratum-target.h. */ 2147d62b00eSchristos 2157d62b00eSchristos void 2167d62b00eSchristos switch_to_target_no_thread (process_stratum_target *target) 2177d62b00eSchristos { 2187d62b00eSchristos for (inferior *inf : all_inferiors (target)) 2197d62b00eSchristos { 2207d62b00eSchristos switch_to_inferior_no_thread (inf); 2217d62b00eSchristos break; 2227d62b00eSchristos } 2237f2ac410Schristos } 224