32#include "gdbsupport/environ.h"
37#include "readline/tilde.h"
39#include "gdbsupport/buildargv.h"
64 gdb_assert (
inf != NULL);
122 internal_error (
"pop_all_targets couldn't find target %s\n",
255 thr->
ptid.to_string ().c_str ());
275 inf->clear_thread_list ();
286 inf->pop_all_targets ();
289 if (
inf->pspace->empty ())
309 inf->clear_thread_list ();
314 inf->fake_pid_p =
false;
317 if (
inf->vfork_parent != NULL)
319 inf->vfork_parent->vfork_child = NULL;
320 inf->vfork_parent = NULL;
322 if (
inf->vfork_child != NULL)
324 inf->vfork_child->vfork_parent = NULL;
325 inf->vfork_child = NULL;
328 inf->pending_detach =
false;
348 gdb_printf (_(
"[Inferior %d (%s) detached]\n"),
372 inf->has_exit_code =
false;
394 gdb_assert (
pid != 0);
447 if (
inf->has_execution ())
448 for (
thread_info *tp ATTRIBUTE_UNUSED :
inf->non_exited_threads ())
475 if (!
inf->deletable ()
490 return std::distance (rng.begin (), rng.end ());
511 const char *filename =
inf->pspace->exec_filename.get ();
513 if (filename == NULL)
514 filename = _(
"<noexec>");
516 uiout->
message (_(
"[Switching to inferior %d [%s] (%s)]\n"),
526 if (proc_target == NULL)
547 size_t connection_id_len = 20;
556 if (connection_id_len < conn.size ())
557 connection_id_len = conn.size ();
564 uiout->
message (
"No inferiors.\n");
573 "connection-id",
"Connection");
589 if (
inf == current_inf)
605 if (
inf->pspace->exec_filename !=
nullptr)
614 if (
inf->vfork_parent)
616 uiout->
text (_(
"\n\tis vfork child of inferior "));
619 if (
inf->vfork_child)
621 uiout->
text (_(
"\n\tis vfork parent of inferior "));
633 error (_(
"Requires argument (inferior id(s) to detach)"));
645 warning (_(
"Inferior ID %d not known."),
num);
651 warning (_(
"Inferior ID %d is not running."),
num);
658 warning (_(
"Inferior ID %d has no threads."),
num);
672 error (_(
"Requires argument (inferior id(s) to kill)"));
684 warning (_(
"Inferior ID %d not known."),
num);
690 warning (_(
"Inferior ID %d is not running."),
num);
697 warning (_(
"Inferior ID %d has no threads."),
num);
706 bfd_cache_close_all ();
721gdb::optional<scoped_restore_current_thread>
724 gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
727 maybe_restore_thread.emplace ();
731 return maybe_restore_thread;
743 gdb_assert (
inf !=
nullptr);
744 const char *filename =
inf->pspace->exec_filename.get ();
746 if (filename ==
nullptr)
747 filename = _(
"<noexec>");
749 gdb_printf (_(
"[Current inferior is %d [%s] (%s)]\n"),
759 error (_(
"Inferior ID %d not known."),
num);
767 error (_(
"Inferior has no threads."));
801 error (_(
"Requires an argument (inferior id(s) to remove)"));
811 warning (_(
"Inferior ID %d not known."),
num);
815 if (!
inf->deletable ())
817 warning (_(
"Can not remove current inferior %d."),
num);
823 warning (_(
"Can not remove active inferior %d."),
num);
853 gdb_assert (
inf->gdbarch != NULL);
862 bool no_connection,
inferior *org_inf)
871 if (!no_connection && proc_target != NULL)
874 gdb_printf (_(
"Added inferior %d on connection %d (%s)\n"),
889 gdb::unique_xmalloc_ptr<char> exec;
890 symfile_add_flags add_flags = 0;
891 bool no_connection =
false;
898 gdb_argv built_argv (
args);
900 for (
char **argv = built_argv.get (); *argv != NULL; argv++)
904 if (strcmp (*argv,
"-copies") == 0)
908 error (_(
"No argument to -copies"));
911 else if (strcmp (*argv,
"-no-connection") == 0)
912 no_connection =
true;
913 else if (strcmp (*argv,
"-exec") == 0)
917 error (_(
"No argument to -exec"));
918 exec.reset (tilde_expand (*argv));
922 error (_(
"Invalid argument"));
930 for (i = 0; i < copies; ++i)
951 bool no_connection =
false;
955 gdb_argv built_argv (
args);
957 char **argv = built_argv.get ();
958 for (; *argv != NULL; argv++)
962 if (strcmp (*argv,
"-copies") == 0)
966 error (_(
"No argument to -copies"));
970 error (_(
"Invalid copies number"));
972 else if (strcmp (*argv,
"-no-connection") == 0)
973 no_connection =
true;
987 error (_(
"Inferior ID %d not known."),
num);
991 error (_(
"Invalid argument"));
1003 for (i = 0; i < copies; ++i)
1023 if (
inf->tdesc_info.from_user_p ())
1029 inf->set_args (orginf->
args ());
1030 inf->set_cwd (orginf->
cwd ());
1031 inf->set_tty (orginf->
tty ());
1032 for (
const std::string &set_var : orginf->
environment.user_set_env ())
1035 const std::string::size_type pos = set_var.find (
'=');
1036 gdb_assert (pos != std::string::npos);
1037 const std::string varname = set_var.substr (0, pos);
1038 inf->environment.set
1039 (varname.c_str (), orginf->
environment.get (varname.c_str ()));
1041 for (
const std::string &unset_var
1043 inf->environment.unset (unset_var.c_str ());
1059static struct value *
1096 _(
"Print a list of inferiors being managed.\n\
1097Usage: info inferiors [ID]...\n\
1098If IDs are specified, the list is limited to just those inferiors.\n\
1099By default all inferiors are displayed."));
1102Add a new inferior.\n\
1103Usage: add-inferior [-copies N] [-exec FILENAME] [-no-connection]\n\
1104N is the optional number of inferiors to add, default is 1.\n\
1105FILENAME is the file name of the executable to use\n\
1107By default, the new inferior inherits the current inferior's connection.\n\
1108If -no-connection is specified, the new inferior begins with\n\
1109no target connection yet."));
1113Remove inferior ID (or list of IDs).\n\
1114Usage: remove-inferiors ID..."));
1117Clone inferior ID.\n\
1118Usage: clone-inferior [-copies N] [-no-connection] [ID]\n\
1119Add N copies of inferior ID. The new inferiors have the same\n\
1120executable loaded as the copied inferior. If -copies is not specified,\n\
1121adds 1 copy. If ID is not specified, it is the current inferior\n\
1123By default, the new inferiors inherit the copied inferior's connection.\n\
1124If -no-connection is specified, the new inferiors begin with\n\
1125no target connection yet."));
1128Detach from inferior ID (or list of IDS).\n\
1129Usage; detach inferiors ID..."),
1133Kill inferior ID (or list of IDs).\n\
1134Usage: kill inferiors ID..."),
1138Use this command to switch between inferiors.\n\
1139Usage: inferior ID\n\
1140The new inferior ID must be currently known."),
1145Set printing of inferior events (such as inferior start and exit)."), _(
"\
1146Show printing of inferior events (such as inferior start and exit)."), NULL,
struct gdbarch * gdbarch_find_by_info(struct gdbarch_info info)
ui_file_style style() const
target_ops * top_target()
target_desc_info tdesc_info
void pop_all_targets_above(enum strata stratum)
thread_info * find_thread(ptid_t ptid)
int unpush_target(struct target_ops *t)
void set_args(std::string args)
void unpush_target_and_assert(struct target_ops *target)
void do_all_continuations()
const std::string & cwd() const
std::unordered_map< ptid_t, thread_info * > ptid_thread_map
target_stack m_target_stack
void push_target(struct target_ops *t)
struct process_stratum_target * process_target()
const std::string & args() const
void add_continuation(std::function< void()> &&cont)
struct address_space * aspace
void pop_all_targets_at_and_above(enum strata stratum)
const std::string & tty()
inf_non_exited_threads_range non_exited_threads()
void set_tty(std::string terminal_name)
intrusive_list< thread_info > thread_list
std::list< std::function< void()> > m_continuations
struct program_space * pspace
void maybe_remove_resumed_with_pending_wait_status(thread_info *thread)
bool unpush(target_ops *t)
void field_string(const char *fldname, const char *string, const ui_file_style &style=ui_file_style())
void field_signed(const char *fldname, LONGEST value)
void field_skip(const char *fldname)
void text(const char *string)
void table_header(int width, ui_align align, const std::string &col_name, const std::string &col_hdr)
void message(const char *format,...) ATTRIBUTE_PRINTF(2
struct cmd_list_element * showprintlist
struct cmd_list_element * cmdlist
struct cmd_list_element * setprintlist
struct cmd_list_element * detachlist
struct cmd_list_element * killlist
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
void set_cmd_completer(struct cmd_list_element *cmd, completer_ftype *completer)
struct cmd_list_element * add_com(const char *name, enum command_class theclass, cmd_simple_func_ftype *fun, const char *doc)
set_show_commands add_setshow_boolean_cmd(const char *name, enum command_class theclass, bool *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
struct cmd_list_element * add_info(const char *name, cmd_simple_func_ftype *fun, const char *doc)
cli_style_option file_name_style
int number_is_in_list(const char *list, int number)
void filename_completer(struct cmd_list_element *ignore, completion_tracker &tracker, const char *text, const char *word)
LONGEST parse_and_eval_long(const char *exp)
void exec_file_attach(const char *filename, int from_tty)
void reinit_frame_cache(void)
void set_thread_exited(thread_info *tp, gdb::optional< ULONGEST > exit_code={}, bool silent=false)
void switch_to_thread(struct thread_info *thr)
struct thread_info * any_thread_of_inferior(inferior *inf)
#define threads_debug_printf(fmt,...)
void switch_to_no_thread()
void delete_exited_threads(void)
void init_thread_list(void)
gdb::ref_ptr< struct inferior, refcounted_object_ref_policy > inferior_ref
static struct inf * cur_inf(void)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
void detach_command(const char *args, int from_tty)
static void add_inferior_command(const char *args, int from_tty)
void inferior_appeared(struct inferior *inf, int pid)
static void remove_inferior_command(const char *args, int from_tty)
struct inferior * add_inferior_silent(int pid)
struct inferior * add_inferior_with_spaces(void)
void initialize_inferiors(void)
void print_selected_inferior(struct ui_out *uiout)
static std::string inferior_pid_to_str(int pid)
static void notify_inferior_disappeared(inferior *inf)
static inferior_ref current_inferior_
struct inferior * find_inferior_ptid(process_stratum_target *targ, ptid_t ptid)
static struct value * inferior_id_make_value(struct gdbarch *gdbarch, struct internalvar *var, void *ignore)
struct inferior * find_inferior_pid(process_stratum_target *targ, int pid)
static std::string uiout_field_connection(process_stratum_target *proc_target)
void set_current_inferior(struct inferior *inf)
int number_of_inferiors(void)
gdb::optional< scoped_restore_current_thread > maybe_switch_inferior(inferior *inf)
bool print_inferior_events
void delete_inferior(struct inferior *inf)
static void notify_inferior_added(inferior *inf)
static void clone_inferior_command(const char *args, int from_tty)
static void detach_inferior_command(const char *args, int from_tty)
static void notify_inferior_appeared(inferior *inf)
void detach_inferior(inferior *inf)
int have_live_inferiors(void)
void switch_to_inferior_and_push_target(inferior *new_inf, bool no_connection, inferior *org_inf)
static void kill_inferior_command(const char *args, int from_tty)
struct inferior * current_inferior(void)
struct inferior * add_inferior(int pid)
static void notify_inferior_removed(inferior *inf)
struct inferior * find_inferior_for_program_space(struct program_space *pspace)
static int highest_inferior_num
void switch_to_inferior_no_thread(inferior *inf)
static const struct internalvar_funcs inferior_funcs
static void show_print_inferior_events(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
void exit_inferior(struct inferior *inf)
void prune_inferiors(void)
static void inferior_command(const char *args, int from_tty)
static void print_inferior(struct ui_out *uiout, const char *requested_inferiors)
static void info_inferiors_command(const char *args, int from_tty)
intrusive_list< inferior > inferior_list
int number_of_live_inferiors(process_stratum_target *proc_target)
struct inferior * find_inferior_id(int num)
all_inferiors_safe_range all_inferiors_safe()
all_inferiors_range all_inferiors(process_stratum_target *proc_target=nullptr)
inferior * current_inferior()
void switch_to_inferior_no_thread(inferior *inf)
all_non_exited_inferiors_range all_non_exited_inferiors(process_stratum_target *proc_target=nullptr)
void notify_user_selected_context_changed(user_selected_what selection)
void interps_notify_inferior_removed(inferior *inf)
void interps_notify_inferior_added(inferior *inf)
void interps_notify_inferior_disappeared(inferior *inf)
void interps_notify_inferior_appeared(inferior *inf)
observable< struct inferior * > inferior_added
observable< struct inferior * > inferior_exit
observable< struct inferior * > inferior_removed
observable< struct inferior * > inferior_appeared
observable< struct inferior *, struct inferior * > inferior_cloned
static process_stratum_target * as_process_stratum_target(target_ops *target)
struct program_space * current_program_space
void set_current_program_space(struct program_space *pspace)
struct program_space * clone_program_space(struct program_space *dest, struct program_space *src)
struct address_space * maybe_new_address_space(void)
void registers_changed(void)
virtual ~private_inferior()=0
struct address_space * aspace
virtual strata stratum() const =0
const char * shortname() const
void symbol_file_add_main(const char *args, symfile_add_flags add_flags)
std::string make_target_connection_string(process_stratum_target *t)
target_ops * get_dummy_target()
std::string target_pid_to_str(ptid_t ptid)
void gdb_printf(struct ui_file *stream, const char *format,...)
struct internalvar * create_internalvar_type_lazy(const char *name, const struct internalvar_funcs *funcs, void *data)
struct value * value_from_longest(struct type *type, LONGEST num)