123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750 |
- /* Variables that describe the inferior process running under GDB:
- Where it is, why it stopped, and how to step it.
- Copyright (C) 1986-2022 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;
- struct frame_info;
- 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,
- struct frame_info *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,
- struct frame_info *frame,
- const char *args);
- 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_terminal_init_with_pgrp (int pgrp);
- 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 set_inferior_args_vector (int, char **);
- 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
- };
- /* Possible values for gdbarch_call_dummy_location. */
- #define ON_STACK 1
- #define AT_ENTRY_POINT 4
- /* 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);
- /* 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 (target_ops *t)
- { 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 (); }
- /* 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 *, hash_ptid> 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 ()); }
- /* Delete all threads in the thread list. If SILENT, exit threads
- silently. */
- void clear_thread_list (bool silent);
- /* 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);
- };
- /* 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;
- }
- /* 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. */
- struct address_space *aspace = NULL;
- /* 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 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 target vector implementation. */
- 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;
- private:
- /* 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;
- };
- /* 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.
- 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);
- extern void exit_inferior (inferior *inf);
- extern void exit_inferior_silent (inferior *inf);
- extern void exit_inferior_num_silent (int num);
- 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;
- };
- /* 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);
- #endif /* !defined (INFERIOR_H) */
|