| /* Variables that describe the inferior process running under GDB: | 
 |    Where it is, why it stopped, and how to step it. | 
 |  | 
 |    Copyright (C) 1986-2024 Free Software Foundation, Inc. | 
 |  | 
 |    This file is part of GDB. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #if !defined (INFERIOR_H) | 
 | #define INFERIOR_H 1 | 
 |  | 
 | #include <exception> | 
 | #include <list> | 
 |  | 
 | struct target_waitstatus; | 
 | class frame_info_ptr; | 
 | struct ui_file; | 
 | struct type; | 
 | struct gdbarch; | 
 | struct regcache; | 
 | struct ui_out; | 
 | struct terminal_info; | 
 | struct target_desc_info; | 
 | struct inferior; | 
 | struct thread_info; | 
 |  | 
 | /* For bpstat.  */ | 
 | #include "breakpoint.h" | 
 |  | 
 | /* For enum gdb_signal.  */ | 
 | #include "target.h" | 
 |  | 
 | /* For struct frame_id.  */ | 
 | #include "frame.h" | 
 |  | 
 | /* For gdb_environ.  */ | 
 | #include "gdbsupport/environ.h" | 
 |  | 
 | #include "progspace.h" | 
 | #include "registry.h" | 
 |  | 
 | #include "symfile-add-flags.h" | 
 | #include "gdbsupport/refcounted-object.h" | 
 | #include "gdbsupport/forward-scope-exit.h" | 
 | #include "gdbsupport/gdb_unique_ptr.h" | 
 | #include "gdbsupport/intrusive_list.h" | 
 |  | 
 | #include "gdbsupport/common-inferior.h" | 
 | #include "gdbthread.h" | 
 |  | 
 | #include "process-stratum-target.h" | 
 | #include "displaced-stepping.h" | 
 |  | 
 | #include <unordered_map> | 
 |  | 
 | struct infcall_suspend_state; | 
 | struct infcall_control_state; | 
 |  | 
 | extern void restore_infcall_suspend_state (struct infcall_suspend_state *); | 
 | extern void restore_infcall_control_state (struct infcall_control_state *); | 
 |  | 
 | /* A deleter for infcall_suspend_state that calls | 
 |    restore_infcall_suspend_state.  */ | 
 | struct infcall_suspend_state_deleter | 
 | { | 
 |   void operator() (struct infcall_suspend_state *state) const | 
 |   { | 
 |     try | 
 |       { | 
 | 	restore_infcall_suspend_state (state); | 
 |       } | 
 |     catch (const gdb_exception_error &e) | 
 |       { | 
 | 	/* If we are restoring the inferior state due to an exception, | 
 | 	   some error message will be printed.  So, only warn the user | 
 | 	   when we cannot restore during normal execution.  */ | 
 | 	bool unwinding; | 
 | #if __cpp_lib_uncaught_exceptions | 
 | 	unwinding = std::uncaught_exceptions () > 0; | 
 | #else | 
 | 	unwinding = std::uncaught_exception (); | 
 | #endif | 
 | 	if (!unwinding) | 
 | 	  warning (_("Failed to restore inferior state: %s"), e.what ()); | 
 |       } | 
 |   } | 
 | }; | 
 |  | 
 | /* A unique_ptr specialization for infcall_suspend_state.  */ | 
 | typedef std::unique_ptr<infcall_suspend_state, infcall_suspend_state_deleter> | 
 |     infcall_suspend_state_up; | 
 |  | 
 | extern infcall_suspend_state_up save_infcall_suspend_state (); | 
 |  | 
 | /* A deleter for infcall_control_state that calls | 
 |    restore_infcall_control_state.  */ | 
 | struct infcall_control_state_deleter | 
 | { | 
 |   void operator() (struct infcall_control_state *state) const | 
 |   { | 
 |     restore_infcall_control_state (state); | 
 |   } | 
 | }; | 
 |  | 
 | /* A unique_ptr specialization for infcall_control_state.  */ | 
 | typedef std::unique_ptr<infcall_control_state, infcall_control_state_deleter> | 
 |     infcall_control_state_up; | 
 |  | 
 | extern infcall_control_state_up save_infcall_control_state (); | 
 |  | 
 | extern void discard_infcall_suspend_state (struct infcall_suspend_state *); | 
 | extern void discard_infcall_control_state (struct infcall_control_state *); | 
 |  | 
 | extern readonly_detached_regcache * | 
 |   get_infcall_suspend_state_regcache (struct infcall_suspend_state *); | 
 |  | 
 | extern void set_sigint_trap (void); | 
 |  | 
 | extern void clear_sigint_trap (void); | 
 |  | 
 | /* Collected pid, tid, etc. of the debugged inferior.  When there's | 
 |    no inferior, inferior_ptid.pid () will be 0.  */ | 
 |  | 
 | extern ptid_t inferior_ptid; | 
 |  | 
 | extern void generic_mourn_inferior (void); | 
 |  | 
 | extern CORE_ADDR unsigned_pointer_to_address (struct gdbarch *gdbarch, | 
 | 					      struct type *type, | 
 | 					      const gdb_byte *buf); | 
 | extern void unsigned_address_to_pointer (struct gdbarch *gdbarch, | 
 | 					 struct type *type, gdb_byte *buf, | 
 | 					 CORE_ADDR addr); | 
 | extern CORE_ADDR signed_pointer_to_address (struct gdbarch *gdbarch, | 
 | 					    struct type *type, | 
 | 					    const gdb_byte *buf); | 
 | extern void address_to_signed_pointer (struct gdbarch *gdbarch, | 
 | 				       struct type *type, gdb_byte *buf, | 
 | 				       CORE_ADDR addr); | 
 |  | 
 | extern void reopen_exec_file (void); | 
 |  | 
 | /* From misc files */ | 
 |  | 
 | extern void default_print_registers_info (struct gdbarch *gdbarch, | 
 | 					  struct ui_file *file, | 
 | 					  const frame_info_ptr &frame, | 
 | 					  int regnum, int all); | 
 |  | 
 | /* Default implementation of gdbarch_print_float_info.  Print | 
 |    the values of all floating point registers.  */ | 
 |  | 
 | extern void default_print_float_info (struct gdbarch *gdbarch, | 
 | 				      struct ui_file *file, | 
 | 				      const frame_info_ptr &frame, | 
 | 				      const char *args); | 
 |  | 
 | /* Try to determine whether TTY is GDB's input terminal.  Returns | 
 |    TRIBOOL_UNKNOWN if we can't tell.  */ | 
 |  | 
 | extern tribool is_gdb_terminal (const char *tty); | 
 |  | 
 | /* Helper for sharing_input_terminal.  Try to determine whether pid | 
 |    PID is using the same TTY for input as GDB is.  Returns | 
 |    TRIBOOL_UNKNOWN if we can't tell.  */ | 
 |  | 
 | extern tribool sharing_input_terminal (int pid); | 
 |  | 
 | /* The type of the function that is called when SIGINT is handled.  */ | 
 |  | 
 | typedef void c_c_handler_ftype (int); | 
 |  | 
 | /* Install a new SIGINT handler in a host-dependent way.  The previous | 
 |    handler is returned.  It is fine to pass SIG_IGN for FN, but not | 
 |    SIG_DFL.  */ | 
 |  | 
 | extern c_c_handler_ftype *install_sigint_handler (c_c_handler_ftype *fn); | 
 |  | 
 | extern void child_terminal_info (struct target_ops *self, const char *, int); | 
 |  | 
 | extern void child_terminal_ours (struct target_ops *self); | 
 |  | 
 | extern void child_terminal_ours_for_output (struct target_ops *self); | 
 |  | 
 | extern void child_terminal_inferior (struct target_ops *self); | 
 |  | 
 | extern void child_terminal_save_inferior (struct target_ops *self); | 
 |  | 
 | extern void child_terminal_init (struct target_ops *self); | 
 |  | 
 | extern void child_pass_ctrlc (struct target_ops *self); | 
 |  | 
 | extern void child_interrupt (struct target_ops *self); | 
 |  | 
 | /* From fork-child.c */ | 
 |  | 
 | /* Helper function to call STARTUP_INFERIOR with PID and NUM_TRAPS. | 
 |    This function already calls set_executing.  Return the ptid_t from | 
 |    STARTUP_INFERIOR.  */ | 
 | extern ptid_t gdb_startup_inferior (pid_t pid, int num_traps); | 
 |  | 
 | /* From infcmd.c */ | 
 |  | 
 | /* Initial inferior setup.  Determines the exec file is not yet known, | 
 |    takes any necessary post-attaching actions, fetches the target | 
 |    description and syncs the shared library list.  */ | 
 |  | 
 | extern void setup_inferior (int from_tty); | 
 |  | 
 | extern void post_create_inferior (int from_tty); | 
 |  | 
 | extern void attach_command (const char *, int); | 
 |  | 
 | extern void registers_info (const char *, int); | 
 |  | 
 | extern void continue_1 (int all_threads); | 
 |  | 
 | extern void interrupt_target_1 (bool all_threads); | 
 |  | 
 | using delete_longjmp_breakpoint_cleanup | 
 |   = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint); | 
 |  | 
 | extern void detach_command (const char *, int); | 
 |  | 
 | extern void notice_new_inferior (struct thread_info *, bool, int); | 
 |  | 
 | /* Return the value of the result of a function at the end of a 'finish' | 
 |    command/BP.  If the result's value cannot be retrieved, return NULL. | 
 |  | 
 |    FUNC_SYMBOL is the symbol of the function being returned from.  FUNCTION is | 
 |    a value containing the address of the function.  */ | 
 |  | 
 | extern struct value *get_return_value (struct symbol *func_symbol, | 
 | 				       struct value *function); | 
 |  | 
 | /* Prepare for execution command.  TARGET is the target that will run | 
 |    the command.  BACKGROUND determines whether this is a foreground | 
 |    (synchronous) or background (asynchronous) command.  */ | 
 |  | 
 | extern void prepare_execution_command (struct target_ops *target, | 
 | 				       int background); | 
 |  | 
 | /* Nonzero if stopped due to completion of a stack dummy routine.  */ | 
 |  | 
 | extern enum stop_stack_kind stop_stack_dummy; | 
 |  | 
 | /* Nonzero if program stopped due to a random (unexpected) signal in | 
 |    inferior process.  */ | 
 |  | 
 | extern int stopped_by_random_signal; | 
 |  | 
 | /* Print notices on inferior events (attach, detach, etc.), set with | 
 |    `set print inferior-events'.  */ | 
 | extern bool print_inferior_events; | 
 |  | 
 | /* Anything but NO_STOP_QUIETLY means we expect a trap and the caller | 
 |    will handle it themselves.  STOP_QUIETLY is used when running in | 
 |    the shell before the child program has been exec'd and when running | 
 |    through shared library loading.  STOP_QUIETLY_REMOTE is used when | 
 |    setting up a remote connection; it is like STOP_QUIETLY_NO_SIGSTOP | 
 |    except that there is no need to hide a signal.  */ | 
 |  | 
 | /* STOP_QUIETLY_NO_SIGSTOP is used to handle a tricky situation with attach. | 
 |    When doing an attach, the kernel stops the debuggee with a SIGSTOP. | 
 |    On newer GNU/Linux kernels (>= 2.5.61) the handling of SIGSTOP for | 
 |    a ptraced process has changed.  Earlier versions of the kernel | 
 |    would ignore these SIGSTOPs, while now SIGSTOP is treated like any | 
 |    other signal, i.e. it is not muffled. | 
 |  | 
 |    If the gdb user does a 'continue' after the 'attach', gdb passes | 
 |    the global variable stop_signal (which stores the signal from the | 
 |    attach, SIGSTOP) to the ptrace(PTRACE_CONT,...)  call.  This is | 
 |    problematic, because the kernel doesn't ignore such SIGSTOP | 
 |    now.  I.e. it is reported back to gdb, which in turn presents it | 
 |    back to the user. | 
 |  | 
 |    To avoid the problem, we use STOP_QUIETLY_NO_SIGSTOP, which allows | 
 |    gdb to clear the value of stop_signal after the attach, so that it | 
 |    is not passed back down to the kernel.  */ | 
 |  | 
 | enum stop_kind | 
 |   { | 
 |     NO_STOP_QUIETLY = 0, | 
 |     STOP_QUIETLY, | 
 |     STOP_QUIETLY_REMOTE, | 
 |     STOP_QUIETLY_NO_SIGSTOP | 
 |   }; | 
 |  | 
 |  | 
 |  | 
 | /* Base class for target-specific inferior data.  */ | 
 |  | 
 | struct private_inferior | 
 | { | 
 |   virtual ~private_inferior () = 0; | 
 | }; | 
 |  | 
 | /* Inferior process specific part of `struct infcall_control_state'. | 
 |  | 
 |    Inferior thread counterpart is `struct thread_control_state'.  */ | 
 |  | 
 | struct inferior_control_state | 
 | { | 
 |   inferior_control_state () | 
 |     : stop_soon (NO_STOP_QUIETLY) | 
 |   { | 
 |   } | 
 |  | 
 |   explicit inferior_control_state (enum stop_kind when) | 
 |     : stop_soon (when) | 
 |   { | 
 |   } | 
 |  | 
 |   /* See the definition of stop_kind above.  */ | 
 |   enum stop_kind stop_soon; | 
 | }; | 
 |  | 
 | /* Return a pointer to the current inferior.  */ | 
 | extern inferior *current_inferior (); | 
 |  | 
 | extern void set_current_inferior (inferior *); | 
 |  | 
 | /* Switch inferior (and program space) to INF, and switch to no thread | 
 |    selected.  */ | 
 | extern void switch_to_inferior_no_thread (inferior *inf); | 
 |  | 
 | /* Ensure INF is the current inferior. | 
 |  | 
 |    If the current inferior was changed, return an RAII object that will | 
 |    restore the original current context.  */ | 
 | extern std::optional<scoped_restore_current_thread> maybe_switch_inferior | 
 |   (inferior *inf); | 
 |  | 
 | /* Info about an inferior's target description.  There's one of these | 
 |    for each inferior.  */ | 
 |  | 
 | struct target_desc_info | 
 | { | 
 |   /* Returns true if this target description information has been supplied by | 
 |      the user.  */ | 
 |   bool from_user_p () | 
 |   { return !this->filename.empty (); } | 
 |  | 
 |   /* A flag indicating that a description has already been fetched | 
 |      from the target, so it should not be queried again.  */ | 
 |   bool fetched = false; | 
 |  | 
 |   /* The description fetched from the target, or NULL if the target | 
 |      did not supply any description.  Only valid when | 
 |      FETCHED is set.  Only the description initialization | 
 |      code should access this; normally, the description should be | 
 |      accessed through the gdbarch object.  */ | 
 |   const struct target_desc *tdesc = nullptr; | 
 |  | 
 |   /* If not empty, the filename to read a target description from, as set by | 
 |      "set tdesc filename ...". | 
 |  | 
 |      If empty, there is not filename specified by the user.  */ | 
 |   std::string filename; | 
 | }; | 
 |  | 
 | /* GDB represents the state of each program execution with an object | 
 |    called an inferior.  An inferior typically corresponds to a process | 
 |    but is more general and applies also to targets that do not have a | 
 |    notion of processes.  Each run of an executable creates a new | 
 |    inferior, as does each attachment to an existing process. | 
 |    Inferiors have unique internal identifiers that are different from | 
 |    target process ids.  Each inferior may in turn have multiple | 
 |    threads running in it. | 
 |  | 
 |    Inferiors are intrusively refcounted objects.  Unlike thread | 
 |    objects, being the user-selected inferior is considered a strong | 
 |    reference and is thus accounted for in the inferior object's | 
 |    refcount (see set_current_inferior).  When GDB needs to remember | 
 |    the selected inferior to later restore it, GDB temporarily bumps | 
 |    the inferior object's refcount, to prevent something deleting the | 
 |    inferior object before reverting back (e.g., due to a | 
 |    "remove-inferiors" command (see | 
 |    scoped_restore_current_inferior).  All other inferior | 
 |    references are considered weak references.  Inferiors are always | 
 |    listed exactly once in the inferior list, so placing an inferior in | 
 |    the inferior list is an implicit, not counted strong reference.  */ | 
 |  | 
 | class inferior : public refcounted_object, | 
 | 		 public intrusive_list_node<inferior> | 
 | { | 
 | public: | 
 |   explicit inferior (int pid); | 
 |   ~inferior (); | 
 |  | 
 |   /* Returns true if we can delete this inferior.  */ | 
 |   bool deletable () const { return refcount () == 0; } | 
 |  | 
 |   /* Push T in this inferior's target stack.  */ | 
 |   void push_target (struct target_ops *t) | 
 |   { m_target_stack.push (t); } | 
 |  | 
 |   /* An overload that deletes the target on failure.  */ | 
 |   void push_target (target_ops_up &&t) | 
 |   { | 
 |     m_target_stack.push (t.get ()); | 
 |     t.release (); | 
 |   } | 
 |  | 
 |   /* Unpush T from this inferior's target stack.  */ | 
 |   int unpush_target (struct target_ops *t); | 
 |  | 
 |   /* Returns true if T is pushed in this inferior's target stack.  */ | 
 |   bool target_is_pushed (const target_ops *t) const | 
 |   { return m_target_stack.is_pushed (t); } | 
 |  | 
 |   /* Find the target beneath T in this inferior's target stack.  */ | 
 |   target_ops *find_target_beneath (const target_ops *t) | 
 |   { return m_target_stack.find_beneath (t); } | 
 |  | 
 |   /* Return the target at the top of this inferior's target stack.  */ | 
 |   target_ops *top_target () | 
 |   { return m_target_stack.top (); } | 
 |  | 
 |   /* Unpush all targets except the dummy target from m_target_stack.  As | 
 |      targets are removed from m_target_stack their reference count is | 
 |      decremented, which may cause a target to close.  */ | 
 |   void pop_all_targets () | 
 |   { pop_all_targets_above (dummy_stratum); } | 
 |  | 
 |   /* Unpush all targets above STRATUM from m_target_stack.  As targets are | 
 |      removed from m_target_stack their reference count is decremented, | 
 |      which may cause a target to close.  */ | 
 |   void pop_all_targets_above (enum strata stratum); | 
 |  | 
 |   /* Unpush all targets at and above STRATUM from m_target_stack.  As | 
 |      targets are removed from m_target_stack their reference count is | 
 |      decremented, which may cause a target to close.  */ | 
 |   void pop_all_targets_at_and_above (enum strata stratum); | 
 |  | 
 |   /* Return the target at process_stratum level in this inferior's | 
 |      target stack.  */ | 
 |   struct process_stratum_target *process_target () | 
 |   { return (process_stratum_target *) m_target_stack.at (process_stratum); } | 
 |  | 
 |   /* Return the target at STRATUM in this inferior's target stack.  */ | 
 |   target_ops *target_at (enum strata stratum) | 
 |   { return m_target_stack.at (stratum); } | 
 |  | 
 |   bool has_execution () | 
 |   { return target_has_execution (this); } | 
 |  | 
 |   /* This inferior's thread list, sorted by creation order.  */ | 
 |   intrusive_list<thread_info> thread_list; | 
 |  | 
 |   /* A map of ptid_t to thread_info*, for average O(1) ptid_t lookup. | 
 |      Exited threads do not appear in the map.  */ | 
 |   std::unordered_map<ptid_t, thread_info *> ptid_thread_map; | 
 |  | 
 |   /* Returns a range adapter covering the inferior's threads, | 
 |      including exited threads.  Used like this: | 
 |  | 
 |        for (thread_info *thr : inf->threads ()) | 
 | 	 { .... } | 
 |   */ | 
 |   inf_threads_range threads () | 
 |   { return inf_threads_range (this->thread_list.begin ()); } | 
 |  | 
 |   /* Returns a range adapter covering the inferior's non-exited | 
 |      threads.  Used like this: | 
 |  | 
 |        for (thread_info *thr : inf->non_exited_threads ()) | 
 | 	 { .... } | 
 |   */ | 
 |   inf_non_exited_threads_range non_exited_threads () | 
 |   { return inf_non_exited_threads_range (this->thread_list.begin ()); } | 
 |  | 
 |   /* Like inferior::threads(), but returns a range adapter that can be | 
 |      used with range-for, safely.  I.e., it is safe to delete the | 
 |      currently-iterated thread, like this: | 
 |  | 
 |      for (thread_info *t : inf->threads_safe ()) | 
 |        if (some_condition ()) | 
 | 	 delete f; | 
 |   */ | 
 |   inline safe_inf_threads_range threads_safe () | 
 |   { return safe_inf_threads_range (this->thread_list.begin ()); } | 
 |  | 
 |   /* Find (non-exited) thread PTID of this inferior.  */ | 
 |   thread_info *find_thread (ptid_t ptid); | 
 |  | 
 |   /* Delete all threads in the thread list, silently.  */ | 
 |   void clear_thread_list (); | 
 |  | 
 |   /* Continuations-related methods.  A continuation is an std::function | 
 |      to be called to finish the execution of a command when running | 
 |      GDB asynchronously.  A continuation is executed after any thread | 
 |      of this inferior stops.  Continuations are used by the attach | 
 |      command and the remote target when a new inferior is detected.  */ | 
 |   void add_continuation (std::function<void ()> &&cont); | 
 |   void do_all_continuations (); | 
 |  | 
 |   /* Set/get file name for default use for standard in/out in the inferior. | 
 |  | 
 |      On Unix systems, we try to make TERMINAL_NAME the inferior's controlling | 
 |      terminal. | 
 |  | 
 |      If TERMINAL_NAME is the empty string, then the inferior inherits GDB's | 
 |      terminal (or GDBserver's if spawning a remote process).  */ | 
 |   void set_tty (std::string terminal_name); | 
 |   const std::string &tty (); | 
 |  | 
 |   /* Set the argument string to use when running this inferior. | 
 |  | 
 |      An empty string can be used to represent "no arguments".  */ | 
 |   void set_args (std::string args) | 
 |   { | 
 |     m_args = std::move (args); | 
 |   }; | 
 |  | 
 |   /* Set the argument string from some strings.  */ | 
 |   void set_args (gdb::array_view<char * const> args); | 
 |  | 
 |   /* Get the argument string to use when running this inferior. | 
 |  | 
 |      No arguments is represented by an empty string.  */ | 
 |   const std::string &args () const | 
 |   { | 
 |     return m_args; | 
 |   } | 
 |  | 
 |   /* Set the inferior current working directory. | 
 |  | 
 |      If CWD is empty, unset the directory.  */ | 
 |   void set_cwd (std::string cwd) | 
 |   { | 
 |     m_cwd = std::move (cwd); | 
 |   } | 
 |  | 
 |   /* Get the inferior current working directory. | 
 |  | 
 |      Return an empty string if the current working directory is not | 
 |      specified.  */ | 
 |   const std::string &cwd () const | 
 |   { | 
 |     return m_cwd; | 
 |   } | 
 |  | 
 |   /* Set this inferior's arch.  */ | 
 |   void set_arch (gdbarch *arch); | 
 |  | 
 |   /* Get this inferior's arch.  */ | 
 |   gdbarch *arch () | 
 |   { return m_gdbarch; } | 
 |  | 
 |   /* Convenient handle (GDB inferior id).  Unique across all | 
 |      inferiors.  */ | 
 |   int num = 0; | 
 |  | 
 |   /* Actual target inferior id, usually, a process id.  This matches | 
 |      the ptid_t.pid member of threads of this inferior.  */ | 
 |   int pid = 0; | 
 |   /* True if the PID was actually faked by GDB.  */ | 
 |   bool fake_pid_p = false; | 
 |  | 
 |   /* The highest thread number this inferior ever had.  */ | 
 |   int highest_thread_num = 0; | 
 |  | 
 |   /* State of GDB control of inferior process execution. | 
 |      See `struct inferior_control_state'.  */ | 
 |   inferior_control_state control; | 
 |  | 
 |   /* True if this was an auto-created inferior, e.g. created from | 
 |      following a fork; false, if this inferior was manually added by | 
 |      the user, and we should not attempt to prune it | 
 |      automatically.  */ | 
 |   bool removable = false; | 
 |  | 
 |   /* The address space bound to this inferior.  */ | 
 |   address_space_ref_ptr aspace; | 
 |  | 
 |   /* The program space bound to this inferior.  */ | 
 |   struct program_space *pspace = NULL; | 
 |  | 
 |   /* The terminal state as set by the last target_terminal::terminal_* | 
 |      call.  */ | 
 |   target_terminal_state terminal_state = target_terminal_state::is_ours; | 
 |  | 
 |   /* Environment to use for running inferior, | 
 |      in format described in environ.h.  */ | 
 |   gdb_environ environment; | 
 |  | 
 |   /* True if this child process was attached rather than forked.  */ | 
 |   bool attach_flag = false; | 
 |  | 
 |   /* If this inferior is a vfork child, then this is the pointer to | 
 |      its vfork parent, if GDB is still attached to it.  */ | 
 |   inferior *vfork_parent = NULL; | 
 |  | 
 |   /* If this process is a vfork parent, this is the pointer to the | 
 |      child.  Since a vfork parent is left frozen by the kernel until | 
 |      the child execs or exits, a process can only have one vfork child | 
 |      at a given time.  */ | 
 |   inferior *vfork_child = NULL; | 
 |  | 
 |   /* True if this inferior should be detached when it's vfork sibling | 
 |      exits or execs.  */ | 
 |   bool pending_detach = false; | 
 |  | 
 |   /* If non-nullptr, points to a thread that called vfork and is now waiting | 
 |      for a vfork child not under our control to be done with the shared memory | 
 |      region, either by exiting or execing.  */ | 
 |   thread_info *thread_waiting_for_vfork_done = nullptr; | 
 |  | 
 |   /* True if we're in the process of detaching from this inferior.  */ | 
 |   bool detaching = false; | 
 |  | 
 |   /* True if setup_inferior wasn't called for this inferior yet. | 
 |      Until that is done, we must not access inferior memory or | 
 |      registers, as we haven't determined the target | 
 |      architecture/description.  */ | 
 |   bool needs_setup = false; | 
 |  | 
 |   /* True if the inferior is starting up (inside startup_inferior), | 
 |      and we're nursing it along (through the shell) until it is ready | 
 |      to execute its first instruction.  Until that is done, we must | 
 |      not access inferior memory or registers, as we haven't determined | 
 |      the target architecture/description.  */ | 
 |   bool starting_up = false; | 
 |  | 
 |   /* True when we are reading the library list of the inferior during an | 
 |      attach or handling a fork child.  */ | 
 |   bool in_initial_library_scan = false; | 
 |  | 
 |   /* Private data used by the process_stratum target.  */ | 
 |   std::unique_ptr<private_inferior> priv; | 
 |  | 
 |   /* HAS_EXIT_CODE is true if the inferior exited with an exit code. | 
 |      In this case, the EXIT_CODE field is also valid.  */ | 
 |   bool has_exit_code = false; | 
 |   LONGEST exit_code = 0; | 
 |  | 
 |   /* Default flags to pass to the symbol reading functions.  These are | 
 |      used whenever a new objfile is created.  */ | 
 |   symfile_add_flags symfile_flags = 0; | 
 |  | 
 |   /* Info about an inferior's target description (if it's fetched; the | 
 |      user supplied description's filename, if any; etc.).  */ | 
 |   target_desc_info tdesc_info; | 
 |  | 
 |   /* Data related to displaced stepping.  */ | 
 |   displaced_step_inferior_state displaced_step_state; | 
 |  | 
 |   /* Per inferior data-pointers required by other GDB modules.  */ | 
 |   registry<inferior> registry_fields; | 
 |  | 
 | private: | 
 |  | 
 |   /* Unpush TARGET and assert that it worked.  */ | 
 |   void unpush_target_and_assert (struct target_ops *target); | 
 |  | 
 |   /* The inferior's target stack.  */ | 
 |   target_stack m_target_stack; | 
 |  | 
 |   /* The name of terminal device to use for I/O.  */ | 
 |   std::string m_terminal; | 
 |  | 
 |   /* The list of continuations.  */ | 
 |   std::list<std::function<void ()>> m_continuations; | 
 |  | 
 |   /* The arguments string to use when running.  */ | 
 |   std::string m_args; | 
 |  | 
 |   /* The current working directory that will be used when starting | 
 |      this inferior.  */ | 
 |   std::string m_cwd; | 
 |  | 
 |   /* The architecture associated with the inferior through the | 
 |      connection to the target. | 
 |  | 
 |      The architecture vector provides some information that is really | 
 |      a property of the inferior, accessed through a particular target: | 
 |      ptrace operations; the layout of certain RSP packets; the | 
 |      solib_ops vector; etc.  To differentiate architecture accesses to | 
 |      per-inferior/target properties from | 
 |      per-thread/per-frame/per-objfile properties, accesses to | 
 |      per-inferior/target properties should be made through | 
 |      this gdbarch.  */ | 
 |   gdbarch *m_gdbarch = nullptr; | 
 | }; | 
 |  | 
 | /* Add an inferior to the inferior list, print a message that a new | 
 |    inferior is found, and return the pointer to the new inferior. | 
 |    Caller may use this pointer to initialize the private inferior | 
 |    data.  */ | 
 | extern struct inferior *add_inferior (int pid); | 
 |  | 
 | /* Same as add_inferior, but don't print new inferior notifications to | 
 |    the CLI.  */ | 
 | extern struct inferior *add_inferior_silent (int pid); | 
 |  | 
 | extern void delete_inferior (struct inferior *todel); | 
 |  | 
 | /* Delete an existing inferior list entry, due to inferior detaching.  */ | 
 | extern void detach_inferior (inferior *inf); | 
 |  | 
 | /* Notify observers and interpreters that INF has gone away.  Reset the INF | 
 |    object back to an default, empty, state.  Clear register and frame | 
 |    caches.  */ | 
 | extern void exit_inferior (inferior *inf); | 
 |  | 
 | extern void inferior_appeared (struct inferior *inf, int pid); | 
 |  | 
 | /* Search function to lookup an inferior of TARG by target 'pid'.  */ | 
 | extern struct inferior *find_inferior_pid (process_stratum_target *targ, | 
 | 					   int pid); | 
 |  | 
 | /* Search function to lookup an inferior of TARG whose pid is equal to | 
 |    'ptid.pid'. */ | 
 | extern struct inferior *find_inferior_ptid (process_stratum_target *targ, | 
 | 					    ptid_t ptid); | 
 |  | 
 | /* Search function to lookup an inferior by GDB 'num'.  */ | 
 | extern struct inferior *find_inferior_id (int num); | 
 |  | 
 | /* Find an inferior bound to PSPACE, giving preference to the current | 
 |    inferior.  */ | 
 | extern struct inferior * | 
 |   find_inferior_for_program_space (struct program_space *pspace); | 
 |  | 
 | /* Returns true if the inferior list is not empty.  */ | 
 | extern int have_inferiors (void); | 
 |  | 
 | /* Returns the number of live inferiors running on PROC_TARGET (real | 
 |    live processes with execution).  */ | 
 | extern int number_of_live_inferiors (process_stratum_target *proc_target); | 
 |  | 
 | /* Returns true if there are any live inferiors in the inferior list | 
 |    (not cores, not executables, real live processes).  */ | 
 | extern int have_live_inferiors (void); | 
 |  | 
 | /* Save/restore the current inferior.  */ | 
 |  | 
 | class scoped_restore_current_inferior | 
 | { | 
 | public: | 
 |   scoped_restore_current_inferior () | 
 |     : m_saved_inf (current_inferior ()) | 
 |   {} | 
 |  | 
 |   ~scoped_restore_current_inferior () | 
 |   { set_current_inferior (m_saved_inf); } | 
 |  | 
 |   DISABLE_COPY_AND_ASSIGN (scoped_restore_current_inferior); | 
 |  | 
 | private: | 
 |   inferior *m_saved_inf; | 
 | }; | 
 |  | 
 | /* When reading memory from an inferior, the global inferior_ptid must | 
 |    also be set.  This class arranges to save and restore the necessary | 
 |    state for reading or writing memory, but without invalidating the | 
 |    frame cache.  */ | 
 |  | 
 | class scoped_restore_current_inferior_for_memory | 
 | { | 
 | public: | 
 |  | 
 |   /* Save the current globals and switch to the given inferior and the | 
 |      inferior's program space.  inferior_ptid is set to point to the | 
 |      inferior's process id (and not to any particular thread).  */ | 
 |   explicit scoped_restore_current_inferior_for_memory (inferior *inf) | 
 |     : m_save_ptid (&inferior_ptid) | 
 |   { | 
 |     set_current_inferior (inf); | 
 |     set_current_program_space (inf->pspace); | 
 |     inferior_ptid = ptid_t (inf->pid); | 
 |   } | 
 |  | 
 |   DISABLE_COPY_AND_ASSIGN (scoped_restore_current_inferior_for_memory); | 
 |  | 
 | private: | 
 |  | 
 |   scoped_restore_current_inferior m_save_inferior; | 
 |   scoped_restore_current_program_space m_save_progspace; | 
 |   scoped_restore_tmpl<ptid_t> m_save_ptid; | 
 | }; | 
 |  | 
 |  | 
 | /* Traverse all inferiors.  */ | 
 |  | 
 | extern intrusive_list<inferior> inferior_list; | 
 |  | 
 | /* Pull in the internals of the inferiors ranges and iterators.  Must | 
 |    be done after struct inferior is defined.  */ | 
 | #include "inferior-iter.h" | 
 |  | 
 | /* Return a range that can be used to walk over all inferiors | 
 |    inferiors, with range-for, safely.  I.e., it is safe to delete the | 
 |    currently-iterated inferior.  When combined with range-for, this | 
 |    allow convenient patterns like this: | 
 |  | 
 |      for (inferior *inf : all_inferiors_safe ()) | 
 |        if (some_condition ()) | 
 | 	 delete inf; | 
 | */ | 
 |  | 
 | inline all_inferiors_safe_range | 
 | all_inferiors_safe () | 
 | { | 
 |   return all_inferiors_safe_range (nullptr, inferior_list); | 
 | } | 
 |  | 
 | /* Returns a range representing all inferiors, suitable to use with | 
 |    range-for, like this: | 
 |  | 
 |    for (inferior *inf : all_inferiors ()) | 
 |      [...] | 
 | */ | 
 |  | 
 | inline all_inferiors_range | 
 | all_inferiors (process_stratum_target *proc_target = nullptr) | 
 | { | 
 |   return all_inferiors_range (proc_target, inferior_list); | 
 | } | 
 |  | 
 | /* Return a range that can be used to walk over all inferiors with PID | 
 |    not zero, with range-for.  */ | 
 |  | 
 | inline all_non_exited_inferiors_range | 
 | all_non_exited_inferiors (process_stratum_target *proc_target = nullptr) | 
 | { | 
 |   return all_non_exited_inferiors_range (proc_target, inferior_list); | 
 | } | 
 |  | 
 | /* Prune away automatically added inferiors that aren't required | 
 |    anymore.  */ | 
 | extern void prune_inferiors (void); | 
 |  | 
 | extern int number_of_inferiors (void); | 
 |  | 
 | extern struct inferior *add_inferior_with_spaces (void); | 
 |  | 
 | /* Print the current selected inferior.  */ | 
 | extern void print_selected_inferior (struct ui_out *uiout); | 
 |  | 
 | /* Switch to inferior NEW_INF, a new inferior, and unless | 
 |    NO_CONNECTION is true, push the process_stratum_target of ORG_INF | 
 |    to NEW_INF.  */ | 
 |  | 
 | extern void switch_to_inferior_and_push_target | 
 |   (inferior *new_inf, bool no_connection, inferior *org_inf); | 
 |  | 
 | /* Return true if ID is a valid global inferior number.  */ | 
 |  | 
 | inline bool | 
 | valid_global_inferior_id (int id) | 
 | { | 
 |   for (inferior *inf : all_inferiors ()) | 
 |     if (inf->num == id) | 
 |       return true; | 
 |   return false; | 
 | } | 
 |  | 
 | #endif /* !defined (INFERIOR_H) */ |