/* Variables that describe the inferior process running under GDB:
Where it is, why it stopped, and how to step it.
- Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
struct regcache;
struct ui_out;
struct terminal_info;
+struct target_desc_info;
+struct continuation;
+struct inferior;
+struct thread_info;
/* For bpstat. */
#include "breakpoint.h"
-/* For enum target_signal. */
+/* For enum gdb_signal. */
#include "target.h"
/* For struct frame_id. */
#include "frame.h"
-/* Two structures are used to record inferior state.
+/* For gdb_environ. */
+#include "gdbsupport/environ.h"
- inferior_thread_state contains state about the program itself like its
- registers and any signal it received when it last stopped.
- This state must be restored regardless of how the inferior function call
- ends (either successfully, or after it hits a breakpoint or signal)
- if the program is to properly continue where it left off.
+#include "progspace.h"
+#include "registry.h"
- inferior_status contains state regarding gdb's control of the inferior
- itself like stepping control. It also contains session state like the
- user's currently selected frame.
+#include "symfile-add-flags.h"
+#include "gdbsupport/refcounted-object.h"
+#include "gdbsupport/forward-scope-exit.h"
- Call these routines around hand called functions, including function calls
- in conditional breakpoints for example. */
+#include "gdbsupport/common-inferior.h"
+#include "gdbthread.h"
-struct inferior_thread_state;
-struct inferior_status;
+struct infcall_suspend_state;
+struct infcall_control_state;
-extern struct inferior_thread_state *save_inferior_thread_state (void);
-extern struct inferior_status *save_inferior_status (void);
+extern void restore_infcall_suspend_state (struct infcall_suspend_state *);
+extern void restore_infcall_control_state (struct infcall_control_state *);
-extern void restore_inferior_thread_state (struct inferior_thread_state *);
-extern void restore_inferior_status (struct inferior_status *);
-
-extern struct cleanup *make_cleanup_restore_inferior_thread_state (struct inferior_thread_state *);
-extern struct cleanup *make_cleanup_restore_inferior_status (struct inferior_status *);
-
-extern void discard_inferior_thread_state (struct inferior_thread_state *);
-extern void discard_inferior_status (struct inferior_status *);
-
-extern struct regcache *get_inferior_thread_state_regcache (struct inferior_thread_state *);
-
-/* The -1 ptid, often used to indicate either an error condition
- or a "don't care" condition, i.e, "run all threads." */
-extern ptid_t minus_one_ptid;
-
-/* The null or zero ptid, often used to indicate no process. */
-extern ptid_t null_ptid;
-
-/* Attempt to find and return an existing ptid with the given PID, LWP,
- and TID components. If none exists, create a new one and return
- that. */
-ptid_t ptid_build (int pid, long lwp, long tid);
+/* 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. */
+ if (!std::uncaught_exception ())
+ warning (_("Failed to restore inferior state: %s"), e.what ());
+ }
+ }
+};
-/* Find/Create a ptid from just a pid. */
-ptid_t pid_to_ptid (int pid);
+/* A unique_ptr specialization for infcall_suspend_state. */
+typedef std::unique_ptr<infcall_suspend_state, infcall_suspend_state_deleter>
+ infcall_suspend_state_up;
-/* Fetch the pid (process id) component from a ptid. */
-int ptid_get_pid (ptid_t ptid);
+extern infcall_suspend_state_up save_infcall_suspend_state ();
-/* Fetch the lwp (lightweight process) component from a ptid. */
-long ptid_get_lwp (ptid_t ptid);
+/* 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);
+ }
+};
-/* Fetch the tid (thread id) component from a ptid. */
-long ptid_get_tid (ptid_t ptid);
+/* A unique_ptr specialization for infcall_control_state. */
+typedef std::unique_ptr<infcall_control_state, infcall_control_state_deleter>
+ infcall_control_state_up;
-/* Compare two ptids to see if they are equal */
-extern int ptid_equal (ptid_t p1, ptid_t p2);
+extern infcall_control_state_up save_infcall_control_state ();
-/* Return true if PTID represents a process id. */
-extern int ptid_is_pid (ptid_t ptid);
+extern void discard_infcall_suspend_state (struct infcall_suspend_state *);
+extern void discard_infcall_control_state (struct infcall_control_state *);
-/* Save value of inferior_ptid so that it may be restored by
- a later call to do_cleanups(). Returns the struct cleanup
- pointer needed for later doing the cleanup. */
-extern struct cleanup * save_inferior_ptid (void);
+extern readonly_detached_regcache *
+ get_infcall_suspend_state_regcache (struct infcall_suspend_state *);
extern void set_sigint_trap (void);
extern const char *get_inferior_io_terminal (void);
/* Collected pid, tid, etc. of the debugged inferior. When there's
- no inferior, PIDGET (inferior_ptid) will be 0. */
+ no inferior, inferior_ptid.pid () will be 0. */
extern ptid_t inferior_ptid;
-/* Are we simulating synchronous execution? This is used in async gdb
- to implement the 'run', 'continue' etc commands, which will not
- redisplay the prompt until the execution is actually over. */
-extern int sync_execution;
-
-/* Inferior environment. */
-
-extern struct gdb_environ *inferior_environ;
-
-extern void clear_proceed_status (void);
-
-extern void proceed (CORE_ADDR, enum target_signal, int);
-
-extern int sched_multi;
-
-/* When set, stop the 'step' command if we enter a function which has
- no line number information. The normal behavior is that we step
- over such function. */
-extern int step_stop_if_no_debug;
-
-/* If set, the inferior should be controlled in non-stop mode. In
- this mode, each thread is controlled independently. Execution
- commands apply only to the the selected thread by default, and stop
- events stop only the thread that had the event -- the other threads
- are kept running freely. */
-extern int non_stop;
-
extern void generic_mourn_inferior (void);
-extern void terminal_save_ours (void);
-
-extern void terminal_ours (void);
-
extern CORE_ADDR unsigned_pointer_to_address (struct gdbarch *gdbarch,
struct type *type,
const gdb_byte *buf);
struct type *type, gdb_byte *buf,
CORE_ADDR addr);
-extern void wait_for_inferior (int treat_exec_as_sigtrap);
-
-extern void fetch_inferior_event (void *);
-
-extern void init_wait_for_inferior (void);
-
-extern void close_exec_file (void);
-
extern void reopen_exec_file (void);
-/* The `resume' routine should only be called in special circumstances.
- Normally, use `proceed', which handles a lot of bookkeeping. */
-
-extern void resume (int, enum target_signal);
-
/* From misc files */
extern void default_print_registers_info (struct gdbarch *gdbarch,
struct frame_info *frame,
int regnum, int all);
-extern void child_terminal_info (char *, int);
-
-extern void term_info (char *, int);
-
-extern void terminal_ours_for_output (void);
-
-extern void terminal_inferior (void);
+/* Default implementation of gdbarch_print_float_info. Print
+ the values of all floating point registers. */
-extern void terminal_init_inferior (void);
+extern void default_print_float_info (struct gdbarch *gdbarch,
+ struct ui_file *file,
+ struct frame_info *frame,
+ const char *args);
-extern void terminal_init_inferior_with_pgrp (int pgrp);
+extern void child_terminal_info (struct target_ops *self, const char *, int);
-/* From fork-child.c */
-
-extern int fork_inferior (char *, char *, char **,
- void (*)(void),
- void (*)(int), void (*)(void), char *);
+extern void child_terminal_ours (struct target_ops *self);
+extern void child_terminal_ours_for_output (struct target_ops *self);
-extern void startup_inferior (int);
-
-extern char *construct_inferior_arguments (int, char **);
+extern void child_terminal_inferior (struct target_ops *self);
-/* From infrun.c */
+extern void child_terminal_save_inferior (struct target_ops *self);
-extern void start_remote (int from_tty);
+extern void child_terminal_init (struct target_ops *self);
-extern void normal_stop (void);
+extern void child_terminal_init_with_pgrp (int pgrp);
-extern int signal_stop_state (int);
+extern void child_pass_ctrlc (struct target_ops *self);
-extern int signal_print_state (int);
+extern void child_interrupt (struct target_ops *self);
-extern int signal_pass_state (int);
-
-extern int signal_stop_update (int, int);
-
-extern int signal_print_update (int, int);
-
-extern int signal_pass_update (int, int);
-
-extern void get_last_target_status(ptid_t *ptid,
- struct target_waitstatus *status);
-
-extern void follow_inferior_reset_breakpoints (void);
+/* From fork-child.c */
-/* Throw an error indicating the current thread is running. */
-extern void error_is_running (void);
+/* 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);
-/* Calls error_is_running if the current thread is running. */
-extern void ensure_not_running (void);
+extern char *construct_inferior_arguments (int, char **);
/* From infcmd.c */
-extern void tty_command (char *, int);
+/* 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 (struct target_ops *, int);
-extern void attach_command (char *, int);
+extern void attach_command (const char *, int);
-extern char *get_inferior_args (void);
+extern const char *get_inferior_args (void);
-extern char *set_inferior_args (char *);
+extern void set_inferior_args (const char *);
extern void set_inferior_args_vector (int, char **);
-extern void registers_info (char *, int);
-
-extern void nexti_command (char *, int);
-
-extern void stepi_command (char *, int);
+extern void registers_info (const char *, int);
extern void continue_1 (int all_threads);
-extern void continue_command (char *, int);
+extern void interrupt_target_1 (int all_threads);
-extern void interrupt_target_command (char *args, int from_tty);
+using delete_longjmp_breakpoint_cleanup
+ = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint);
-extern void interrupt_target_1 (int all_threads);
+extern void detach_command (const char *, int);
-extern void detach_command (char *, int);
+extern void notice_new_inferior (struct thread_info *, int, int);
-extern void notice_new_inferior (ptid_t, int, int);
+extern struct value *get_return_value (struct value *function,
+ struct type *value_type);
-/* Address at which inferior stopped. */
+/* 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 CORE_ADDR stop_pc;
+extern void prepare_execution_command (struct target_ops *target,
+ int background);
/* Nonzero if stopped due to completion of a stack dummy routine. */
-extern int stop_stack_dummy;
+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;
-/* STEP_OVER_ALL means step over all subroutine calls.
- STEP_OVER_UNDEBUGGABLE means step over calls to undebuggable functions.
- STEP_OVER_NONE means don't step over any subroutine calls. */
-
-enum step_over_calls_kind
- {
- STEP_OVER_NONE,
- STEP_OVER_ALL,
- STEP_OVER_UNDEBUGGABLE
- };
+/* 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
setting up a remote connection; it is like STOP_QUIETLY_NO_SIGSTOP
except that there is no need to hide a signal. */
-/* It is also used after attach, due to attaching to a process. This
- is a bit trickier. 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.
-
+/* 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
+ 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. */
STOP_QUIETLY_NO_SIGSTOP
};
-/* Reverse execution. */
-enum exec_direction_kind
- {
- EXEC_FORWARD,
- EXEC_REVERSE,
- EXEC_ERROR
- };
+\f
+/* Possible values for gdbarch_call_dummy_location. */
+#define ON_STACK 1
+#define AT_ENTRY_POINT 4
-extern enum exec_direction_kind execution_direction;
+/* Base class for target-specific inferior data. */
-/* Save register contents here when executing a "finish" command or are
- about to pop a stack dummy frame, if-and-only-if proceed_to_finish is set.
- Thus this contains the return value from the called function (assuming
- values are returned in a register). */
+struct private_inferior
+{
+ virtual ~private_inferior () = 0;
+};
-extern struct regcache *stop_registers;
+/* Inferior process specific part of `struct infcall_control_state'.
-/* True if we are debugging displaced stepping. */
-extern int debug_displaced;
+ Inferior thread counterpart is `struct thread_control_state'. */
-/* Dump LEN bytes at BUF in hex to FILE, followed by a newline. */
-void displaced_step_dump_bytes (struct ui_file *file,
- const gdb_byte *buf, size_t len);
+struct inferior_control_state
+{
+ inferior_control_state ()
+ : stop_soon (NO_STOP_QUIETLY)
+ {
+ }
-\f
-/* Possible values for gdbarch_call_dummy_location. */
-#define ON_STACK 1
-#define AT_ENTRY_POINT 4
-#define AT_SYMBOL 5
-
-/* If STARTUP_WITH_SHELL is set, GDB's "run"
- will attempts to start up the debugee under a shell.
- This is in order for argument-expansion to occur. E.g.,
- (gdb) run *
- The "*" gets expanded by the shell into a list of files.
- While this is a nice feature, it turns out to interact badly
- with some of the catch-fork/catch-exec features we have added.
- In particular, if the shell does any fork/exec's before
- the exec of the target program, that can confuse GDB.
- To disable this feature, set STARTUP_WITH_SHELL to 0.
- To enable this feature, set STARTUP_WITH_SHELL to 1.
- The catch-exec traps expected during start-up will
- be 1 if target is not started up with a shell, 2 if it is.
- - RT
- If you disable this, you need to decrement
- START_INFERIOR_TRAPS_EXPECTED in tm.h. */
-#define STARTUP_WITH_SHELL 1
-#if !defined(START_INFERIOR_TRAPS_EXPECTED)
-#define START_INFERIOR_TRAPS_EXPECTED 2
-#endif
-
-struct private_inferior;
+ 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 *);
/* GDB represents the state of each program execution with an object
called an inferior. An inferior typically corresponds to a process
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. */
-
-struct inferior
+ 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:
+ explicit inferior (int pid);
+ ~inferior ();
+
+ /* Returns true if we can delete this inferior. */
+ bool deletable () const { return refcount () == 0; }
+
/* Pointer to next inferior in singly-linked list of inferiors. */
- struct inferior *next;
+ struct inferior *next = NULL;
+
+ /* This inferior's thread list. */
+ thread_info *thread_list = nullptr;
+
+ /* 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); }
+
+ /* 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); }
+
+ /* 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); }
/* Convenient handle (GDB inferior id). Unique across all
inferiors. */
- int num;
+ 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;
+ int pid = 0;
+ /* True if the PID was actually faked by GDB. */
+ bool fake_pid_p = false;
- /* See the definition of stop_kind above. */
- enum stop_kind stop_soon;
+ /* 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;
- /* Nonzero if this child process was attached rather than
- forked. */
- int attach_flag;
+ /* The address space bound to this inferior. */
+ struct address_space *aspace = NULL;
+
+ /* The program space bound to this inferior. */
+ struct program_space *pspace = NULL;
+
+ /* The arguments string to use when running. */
+ char *args = NULL;
+
+ /* The size of elements in argv. */
+ int argc = 0;
+
+ /* The vector version of arguments. If ARGC is nonzero,
+ then we must compute ARGS from this (via the target).
+ This is always coming from main's argv and therefore
+ should never be freed. */
+ char **argv = NULL;
+
+ /* The current working directory that will be used when starting
+ this inferior. */
+ gdb::unique_xmalloc_ptr<char> cwd;
+
+ /* The name of terminal device to use for I/O. */
+ char *terminal = 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;
+
+ /* True if this inferior is a vfork parent waiting for a vfork child
+ not under our control to be done with the shared memory region,
+ either by exiting or execing. */
+ bool waiting_for_vfork_done = false;
+
+ /* True if we're in the process of detaching from this inferior. */
+ bool detaching = false;
/* What is left to do for an execution command after any thread of
this inferior stops. For continuations associated with a
specific thread, see `struct thread_info'. */
- struct continuation *continuations;
+ continuation *continuations = NULL;
- /* Terminal info and state managed by inflow.c. */
- struct terminal_info *terminal_info;
+ /* 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;
/* Private data used by the target vector implementation. */
- struct private_inferior *private;
+ 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 = NULL;
+
+ /* 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. */
+ struct gdbarch *gdbarch = NULL;
+
+ /* Data related to displaced stepping. */
+ displaced_step_inferior_state displaced_step_state;
+
+ /* Per inferior data-pointers required by other GDB modules. */
+ REGISTRY_FIELDS;
};
-/* Create an empty inferior list, or empty the existing one. */
-extern void init_inferior_list (void);
+/* Keep a registry of per-inferior data-pointers required by other GDB
+ modules. */
+
+DECLARE_REGISTRY (inferior);
/* Add an inferior to the inferior list, print a message that a new
inferior is found, and return the pointer to the new inferior.
the CLI. */
extern struct inferior *add_inferior_silent (int pid);
-/* Delete an existing inferior list entry, due to inferior exit. */
-extern void delete_inferior (int pid);
-
-/* Same as delete_inferior, but don't print new inferior notifications
- to the CLI. */
-extern void delete_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 (int pid);
+extern void detach_inferior (inferior *inf);
-/* Get rid of all inferiors. */
-extern void discard_all_inferiors (void);
+extern void exit_inferior (inferior *inf);
-/* Translate the integer inferior id (GDB's homegrown id, not the system's)
- into a "pid" (which may be overloaded with extra inferior information). */
-extern int gdb_inferior_id_to_pid (int);
+extern void exit_inferior_silent (inferior *inf);
-/* Translate a target 'pid' into the integer inferior id (GDB's
- homegrown id, not the system's). */
-extern int pid_to_gdb_inferior_id (int pid);
+extern void exit_inferior_num_silent (int num);
-/* Boolean test for an already-known pid. */
-extern int in_inferior_list (int pid);
+extern void inferior_appeared (struct inferior *inf, int pid);
-/* Boolean test for an already-known inferior id (GDB's homegrown id,
- not the system's). */
-extern int valid_gdb_inferior_id (int num);
+/* Get rid of all inferiors. */
+extern void discard_all_inferiors (void);
-/* Search function to lookup a inferior by target 'pid'. */
+/* Search function to lookup an inferior by target 'pid'. */
extern struct inferior *find_inferior_pid (int pid);
+/* Search function to lookup an inferior whose pid is equal to 'ptid.pid'. */
+extern struct inferior *find_inferior_ptid (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);
+
/* Inferior iterator function.
Calls a callback function once for each inferior, so long as the
void *),
void *);
-/* Prints the list of inferiors and their details on UIOUT.
-
- If REQUESTED_INFERIOR is not -1, it's the GDB id of the inferior
- that should be printed. Otherwise, all inferiors are printed. */
-extern void print_inferior (struct ui_out *uiout, int requested_inferior);
-
/* Returns true if the inferior list is not empty. */
extern int have_inferiors (void);
+/* Returns the number of live inferiors (real live processes). */
+extern int number_of_live_inferiors (void);
+
/* 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);
-/* Return a pointer to the current inferior. It is an error to call
- this if there is no current inferior. */
-extern struct inferior *current_inferior (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;
+};
+
+
+/* Traverse all inferiors. */
+
+extern struct 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 {};
+}
+
+/* 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 ()
+{
+ return {};
+}
+
+/* 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 ()
+{
+ return {};
+}
+
+/* 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);
#endif /* !defined (INFERIOR_H) */