X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finfcmd.c;h=891da91c806e42612ded631e7063b942e8056d54;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=6c9f885badd7943baa8296772a886d610967590f;hpb=f67c0c9171508672167b6868c67211571421a1c6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 6c9f885bad..891da91c80 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1,6 +1,6 @@ /* Memory-access and commands for "inferior" process, for GDB. - Copyright (C) 1986-2018 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -19,13 +19,12 @@ #include "defs.h" #include "arch-utils.h" -#include #include "symtab.h" #include "gdbtypes.h" #include "frame.h" #include "inferior.h" #include "infrun.h" -#include "environ.h" +#include "gdbsupport/environ.h" #include "value.h" #include "gdbcmd.h" #include "symfile.h" @@ -35,8 +34,6 @@ #include "objfiles.h" #include "completer.h" #include "ui-out.h" -#include "event-top.h" -#include "parser-defs.h" #include "regcache.h" #include "reggroups.h" #include "block.h" @@ -45,7 +42,6 @@ #include "observable.h" #include "target-descriptions.h" #include "user-regs.h" -#include "cli/cli-decode.h" #include "gdbthread.h" #include "valprint.h" #include "inline-frame.h" @@ -53,13 +49,13 @@ #include "inf-loop.h" #include "continuations.h" #include "linespec.h" -#include "cli/cli-utils.h" -#include "infcall.h" #include "thread-fsm.h" #include "top.h" #include "interps.h" -#include "common/gdb_optional.h" +#include "skip.h" +#include "gdbsupport/gdb_optional.h" #include "source.h" +#include "cli/cli-style.h" /* Local functions: */ @@ -94,10 +90,6 @@ static char *inferior_io_terminal_scratch; ptid_t inferior_ptid; -/* Address at which inferior stopped. */ - -CORE_ADDR stop_pc; - /* Nonzero if stopped due to completion of a stack dummy routine. */ enum stop_stack_kind stop_stack_dummy; @@ -107,10 +99,6 @@ enum stop_stack_kind stop_stack_dummy; int stopped_by_random_signal; -/* See inferior.h. */ - -int startup_with_shell = 1; - /* Accessor routines. */ @@ -158,17 +146,15 @@ show_inferior_tty_command (struct ui_file *file, int from_tty, "is \"%s\".\n"), inferior_io_terminal); } -char * +const char * get_inferior_args (void) { if (current_inferior ()->argc != 0) { - char *n; - - n = construct_inferior_arguments (current_inferior ()->argc, - current_inferior ()->argv); - set_inferior_args (n); - xfree (n); + gdb::array_view args (current_inferior ()->argv, + current_inferior ()->argc); + std::string n = construct_inferior_arguments (args); + set_inferior_args (n.c_str ()); } if (current_inferior ()->args == NULL) @@ -217,7 +203,7 @@ show_args_command (struct ui_file *file, int from_tty, deprecated_show_value_hack (file, from_tty, c, get_inferior_args ()); } -/* See common/common-inferior.h. */ +/* See gdbsupport/common-inferior.h. */ void set_inferior_cwd (const char *cwd) @@ -232,7 +218,7 @@ set_inferior_cwd (const char *cwd) inf->cwd.reset (xstrdup (cwd)); } -/* See common/common-inferior.h. */ +/* See gdbsupport/common-inferior.h. */ const char * get_inferior_cwd () @@ -271,125 +257,6 @@ server's cwd if remote debugging.\n")); "when starting the inferior is \"%s\".\n"), cwd); } - -/* Compute command-line string given argument vector. This does the - same shell processing as fork_inferior. */ - -char * -construct_inferior_arguments (int argc, char **argv) -{ - char *result; - - if (startup_with_shell) - { -#ifdef __MINGW32__ - /* This holds all the characters considered special to the - Windows shells. */ - static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n"; - static const char quote = '"'; -#else - /* This holds all the characters considered special to the - typical Unix shells. We include `^' because the SunOS - /bin/sh treats it as a synonym for `|'. */ - static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n"; - static const char quote = '\''; -#endif - int i; - int length = 0; - char *out, *cp; - - /* We over-compute the size. It shouldn't matter. */ - for (i = 0; i < argc; ++i) - length += 3 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0'); - - result = (char *) xmalloc (length); - out = result; - - for (i = 0; i < argc; ++i) - { - if (i > 0) - *out++ = ' '; - - /* Need to handle empty arguments specially. */ - if (argv[i][0] == '\0') - { - *out++ = quote; - *out++ = quote; - } - else - { -#ifdef __MINGW32__ - int quoted = 0; - - if (strpbrk (argv[i], special)) - { - quoted = 1; - *out++ = quote; - } -#endif - for (cp = argv[i]; *cp; ++cp) - { - if (*cp == '\n') - { - /* A newline cannot be quoted with a backslash (it - just disappears), only by putting it inside - quotes. */ - *out++ = quote; - *out++ = '\n'; - *out++ = quote; - } - else - { -#ifdef __MINGW32__ - if (*cp == quote) -#else - if (strchr (special, *cp) != NULL) -#endif - *out++ = '\\'; - *out++ = *cp; - } - } -#ifdef __MINGW32__ - if (quoted) - *out++ = quote; -#endif - } - } - *out = '\0'; - } - else - { - /* In this case we can't handle arguments that contain spaces, - tabs, or newlines -- see breakup_args(). */ - int i; - int length = 0; - - for (i = 0; i < argc; ++i) - { - char *cp = strchr (argv[i], ' '); - if (cp == NULL) - cp = strchr (argv[i], '\t'); - if (cp == NULL) - cp = strchr (argv[i], '\n'); - if (cp != NULL) - error (_("can't handle command-line " - "argument containing whitespace")); - length += strlen (argv[i]) + 1; - } - - result = (char *) xmalloc (length); - result[0] = '\0'; - for (i = 0; i < argc; ++i) - { - if (i > 0) - strcat (result, " "); - strcat (result, argv[i]); - } - } - - return result; -} - /* This function strips the '&' character (indicating background execution) that is added as *the last* of the arguments ARGS of a @@ -425,7 +292,7 @@ strip_bg_char (const char *args, int *bg_char_p) } *bg_char_p = 0; - return gdb::unique_xmalloc_ptr (xstrdup (args)); + return make_unique_xstrdup (args); } /* Common actions to take after creating any sort of inferior, by any @@ -448,17 +315,19 @@ post_create_inferior (struct target_ops *target, int from_tty) /* Now that we know the register layout, retrieve current PC. But if the PC is unavailable (e.g., we're opening a core file with missing registers info), ignore it. */ - stop_pc = 0; - TRY + thread_info *thr = inferior_thread (); + + thr->suspend.stop_pc = 0; + try { - stop_pc = regcache_read_pc (get_current_regcache ()); + regcache *rc = get_thread_regcache (thr); + thr->suspend.stop_pc = regcache_read_pc (rc); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { if (ex.error != NOT_AVAILABLE_ERROR) - throw_exception (ex); + throw; } - END_CATCH if (exec_bfd) { @@ -510,7 +379,7 @@ post_create_inferior (struct target_ops *target, int from_tty) static void kill_if_already_running (int from_tty) { - if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) + if (inferior_ptid != null_ptid && target_has_execution) { /* Bail out before killing the program if we will not be able to restart it. */ @@ -531,7 +400,7 @@ prepare_execution_command (struct target_ops *target, int background) { /* If we get a request for running in the bg but the target doesn't support it, error out. */ - if (background && !target->to_can_async_p (target)) + if (background && !target->can_async_p ()) error (_("Asynchronous execution not supported on this target.")); if (!background) @@ -600,14 +469,17 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how) prepare_execution_command (run_target, async_exec); - if (non_stop && !run_target->to_supports_non_stop (run_target)) + if (non_stop && !run_target->supports_non_stop ()) error (_("The target does not support running in non-stop mode.")); /* Done. Can now set breakpoints, change inferior args, etc. */ /* Insert temporary breakpoint in main function if requested. */ if (run_how == RUN_STOP_AT_MAIN) - tbreak_command (main_name (), 0); + { + std::string arg = string_printf ("-qualified %s", main_name ()); + tbreak_command (arg.c_str (), 0); + } exec_file = get_exec_file (0); @@ -639,10 +511,10 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how) /* We call get_inferior_args() because we might need to compute the value now. */ - run_target->to_create_inferior (run_target, exec_file, - std::string (get_inferior_args ()), - current_inferior ()->environment.envp (), - from_tty); + run_target->create_inferior (exec_file, + std::string (get_inferior_args ()), + current_inferior ()->environment.envp (), + from_tty); /* to_create_inferior should push the target, so after this point we shouldn't refer to run_target again. */ run_target = NULL; @@ -653,14 +525,23 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how) events --- the frontend shouldn't see them as stopped. In all-stop, always finish the state of all threads, as we may be resuming more than just the new process. */ - ptid_t finish_ptid = (non_stop - ? ptid_t (current_inferior ()->pid) - : minus_one_ptid); - scoped_finish_thread_state finish_state (finish_ptid); + process_stratum_target *finish_target; + ptid_t finish_ptid; + if (non_stop) + { + finish_target = current_inferior ()->process_target (); + finish_ptid = ptid_t (current_inferior ()->pid); + } + else + { + finish_target = nullptr; + finish_ptid = minus_one_ptid; + } + scoped_finish_thread_state finish_state (finish_target, finish_ptid); /* Pass zero for FROM_TTY, because at this point the "run" command has done its thing; now we are setting up the running program. */ - post_create_inferior (¤t_target, 0); + post_create_inferior (current_top_target (), 0); /* Queue a pending event so that the program stops immediately. */ if (run_how == RUN_STOP_AT_FIRST_INSN) @@ -723,10 +604,13 @@ proceed_thread_callback (struct thread_info *thread, void *arg) much. If/when GDB gains a way to tell the target `hold this thread stopped until I say otherwise', then we can optimize this. */ - if (!is_stopped (thread->ptid)) + if (thread->state != THREAD_STOPPED) return 0; - switch_to_thread (thread->ptid); + if (!thread->inf->has_execution ()) + return 0; + + switch_to_thread (thread); clear_proceed_status (0); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); return 0; @@ -735,8 +619,8 @@ proceed_thread_callback (struct thread_info *thread, void *arg) static void ensure_valid_thread (void) { - if (ptid_equal (inferior_ptid, null_ptid) - || is_exited (inferior_ptid)) + if (inferior_ptid == null_ptid + || inferior_thread ()->state == THREAD_EXITED) error (_("Cannot execute this command without a live selected thread.")); } @@ -765,7 +649,7 @@ error_is_running (void) static void ensure_not_running (void) { - if (is_running (inferior_ptid)) + if (inferior_thread ()->state == THREAD_RUNNING) error_is_running (); } @@ -819,7 +703,7 @@ static void continue_command (const char *args, int from_tty) { int async_exec; - int all_threads = 0; + bool all_threads_p = false; ERROR_NO_INFERIOR; @@ -831,17 +715,17 @@ continue_command (const char *args, int from_tty) { if (startswith (args, "-a")) { - all_threads = 1; + all_threads_p = true; args += sizeof ("-a") - 1; if (*args == '\0') args = NULL; } } - if (!non_stop && all_threads) + if (!non_stop && all_threads_p) error (_("`-a' is meaningless in all-stop mode.")); - if (args != NULL && all_threads) + if (args != NULL && all_threads_p) error (_("Can't resume all threads and specify " "proceed count simultaneously.")); @@ -855,14 +739,14 @@ continue_command (const char *args, int from_tty) struct thread_info *tp; if (non_stop) - tp = find_thread_ptid (inferior_ptid); + tp = inferior_thread (); else { + process_stratum_target *last_target; ptid_t last_ptid; - struct target_waitstatus ws; - get_last_target_status (&last_ptid, &ws); - tp = find_thread_ptid (last_ptid); + get_last_target_status (&last_target, &last_ptid, nullptr); + tp = find_thread_ptid (last_target, last_ptid); } if (tp != NULL) bs = tp->control.stop_bpstat; @@ -890,32 +774,35 @@ continue_command (const char *args, int from_tty) ERROR_NO_INFERIOR; ensure_not_tfind_mode (); - if (!non_stop || !all_threads) + if (!non_stop || !all_threads_p) { ensure_valid_thread (); ensure_not_running (); } - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); if (from_tty) printf_filtered (_("Continuing.\n")); - continue_1 (all_threads); + continue_1 (all_threads_p); } -/* Record the starting point of a "step" or "next" command. */ +/* Record in TP the starting point of a "step" or "next" command. */ static void -set_step_frame (void) +set_step_frame (thread_info *tp) { + /* This can be removed once this function no longer implicitly relies on the + inferior_ptid value. */ + gdb_assert (inferior_ptid == tp->ptid); + frame_info *frame = get_current_frame (); symtab_and_line sal = find_frame_sal (frame); - set_step_info (frame, sal); + set_step_info (tp, frame, sal); CORE_ADDR pc = get_frame_pc (frame); - thread_info *tp = inferior_thread (); tp->control.step_start_function = find_pc_function (pc); } @@ -949,21 +836,11 @@ nexti_command (const char *count_string, int from_tty) step_1 (1, 1, count_string); } -void -delete_longjmp_breakpoint_cleanup (void *arg) -{ - int thread = * (int *) arg; - delete_longjmp_breakpoint (thread); -} - /* Data for the FSM that manages the step/next/stepi/nexti commands. */ -struct step_command_fsm +struct step_command_fsm : public thread_fsm { - /* The base class. */ - struct thread_fsm thread_fsm; - /* How many steps left in a "step N"-like command. */ int count; @@ -972,39 +849,17 @@ struct step_command_fsm /* If true, this is a stepi/nexti, otherwise a step/step. */ int single_inst; -}; - -static void step_command_fsm_clean_up (struct thread_fsm *self, - struct thread_info *thread); -static int step_command_fsm_should_stop (struct thread_fsm *self, - struct thread_info *thread); -static enum async_reply_reason - step_command_fsm_async_reply_reason (struct thread_fsm *self); -/* step_command_fsm's vtable. */ + explicit step_command_fsm (struct interp *cmd_interp) + : thread_fsm (cmd_interp) + { + } -static struct thread_fsm_ops step_command_fsm_ops = -{ - NULL, - step_command_fsm_clean_up, - step_command_fsm_should_stop, - NULL, /* return_value */ - step_command_fsm_async_reply_reason, + void clean_up (struct thread_info *thread) override; + bool should_stop (struct thread_info *thread) override; + enum async_reply_reason do_async_reply_reason () override; }; -/* Allocate a new step_command_fsm. */ - -static struct step_command_fsm * -new_step_command_fsm (struct interp *cmd_interp) -{ - struct step_command_fsm *sm; - - sm = XCNEW (struct step_command_fsm); - thread_fsm_ctor (&sm->thread_fsm, &step_command_fsm_ops, cmd_interp); - - return sm; -} - /* Prepare for a step/next/etc. command. Any target resource allocated here is undone in the FSM's clean_up method. */ @@ -1024,7 +879,7 @@ step_command_fsm_prepare (struct step_command_fsm *sm, thread->control.stepping_command = 1; } -static int prepare_one_step (struct step_command_fsm *sm); +static int prepare_one_step (thread_info *, struct step_command_fsm *sm); static void step_1 (int skip_subroutines, int single_inst, const char *count_string) @@ -1043,7 +898,7 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string) = strip_bg_char (count_string, &async_exec); count_string = stripped.get (); - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); count = count_string ? parse_and_eval_long (count_string) : 1; @@ -1052,8 +907,8 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string) /* Setup the execution command state machine to handle all the COUNT steps. */ thr = inferior_thread (); - step_sm = new_step_command_fsm (command_interp ()); - thr->thread_fsm = &step_sm->thread_fsm; + step_sm = new step_command_fsm (command_interp ()); + thr->thread_fsm = step_sm; step_command_fsm_prepare (step_sm, skip_subroutines, single_inst, count, thr); @@ -1062,7 +917,7 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string) loop. Let the continuation figure out how many other steps we need to do, and handle them one at the time, through step_once. */ - if (!prepare_one_step (step_sm)) + if (!prepare_one_step (thr, step_sm)) proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); else { @@ -1070,7 +925,7 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string) /* Stepped into an inline frame. Pretend that we've stopped. */ - thread_fsm_clean_up (thr->thread_fsm, thr); + thr->thread_fsm->clean_up (thr); proceeded = normal_stop (); if (!proceeded) inferior_event_handler (INF_EXEC_COMPLETE, NULL); @@ -1084,40 +939,36 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string) return control to the user. If count is > 1, returns false, as we will need to keep going. */ -static int -step_command_fsm_should_stop (struct thread_fsm *self, struct thread_info *tp) +bool +step_command_fsm::should_stop (struct thread_info *tp) { - struct step_command_fsm *sm = (struct step_command_fsm *) self; - if (tp->control.stop_step) { /* There are more steps to make, and we did stop due to ending a stepping range. Do another step. */ - if (--sm->count > 0) - return prepare_one_step (sm); + if (--count > 0) + return prepare_one_step (tp, this); - thread_fsm_set_finished (self); + set_finished (); } - return 1; + return true; } /* Implementation of the 'clean_up' FSM method for stepping commands. */ -static void -step_command_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread) +void +step_command_fsm::clean_up (struct thread_info *thread) { - struct step_command_fsm *sm = (struct step_command_fsm *) self; - - if (!sm->single_inst || sm->skip_subroutines) + if (!single_inst || skip_subroutines) delete_longjmp_breakpoint (thread->global_num); } /* Implementation of the 'async_reply_reason' FSM method for stepping commands. */ -static enum async_reply_reason -step_command_fsm_async_reply_reason (struct thread_fsm *self) +enum async_reply_reason +step_command_fsm::do_async_reply_reason () { return EXEC_ASYNC_END_STEPPING_RANGE; } @@ -1128,19 +979,17 @@ step_command_fsm_async_reply_reason (struct thread_fsm *self) resumed. */ static int -prepare_one_step (struct step_command_fsm *sm) +prepare_one_step (thread_info *tp, struct step_command_fsm *sm) { + /* This can be removed once this function no longer implicitly relies on the + inferior_ptid value. */ + gdb_assert (inferior_ptid == tp->ptid); + if (sm->count > 0) { struct frame_info *frame = get_current_frame (); - /* Don't assume THREAD is a valid thread id. It is set to -1 if - the longjmp breakpoint was not required. Use the - INFERIOR_PTID thread instead, which is the same thread when - THREAD is set. */ - struct thread_info *tp = inferior_thread (); - - set_step_frame (); + set_step_frame (tp); if (!sm->single_inst) { @@ -1148,17 +997,32 @@ prepare_one_step (struct step_command_fsm *sm) /* Step at an inlined function behaves like "down". */ if (!sm->skip_subroutines - && inline_skipped_frames (inferior_ptid)) + && inline_skipped_frames (tp)) { ptid_t resume_ptid; + const char *fn = NULL; + symtab_and_line sal; + struct symbol *sym; /* Pretend that we've ran. */ resume_ptid = user_visible_resume_ptid (1); - set_running (resume_ptid, 1); + set_running (tp->inf->process_target (), resume_ptid, true); + + step_into_inline_frame (tp); - step_into_inline_frame (inferior_ptid); - sm->count--; - return prepare_one_step (sm); + frame = get_current_frame (); + sal = find_frame_sal (frame); + sym = get_frame_function (frame); + + if (sym != NULL) + fn = sym->print_name (); + + if (sal.line == 0 + || !function_name_is_marked_for_skip (fn, sal)) + { + sm->count--; + return prepare_one_step (tp, sm); + } } pc = get_frame_pc (frame); @@ -1207,7 +1071,7 @@ prepare_one_step (struct step_command_fsm *sm) } /* Done. */ - thread_fsm_set_finished (&sm->thread_fsm); + sm->set_finished (); return 1; } @@ -1232,7 +1096,7 @@ jump_command (const char *arg, int from_tty) gdb::unique_xmalloc_ptr stripped = strip_bg_char (arg, &async_exec); arg = stripped.get (); - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); if (!arg) error_no_arg (_("starting address")); @@ -1255,7 +1119,7 @@ jump_command (const char *arg, int from_tty) if (fn != NULL && sfn != fn) { if (!query (_("Line %d is not in `%s'. Jump anyway? "), sal.line, - SYMBOL_PRINT_NAME (fn))) + fn->print_name ())) { error (_("Not confirmed.")); /* NOTREACHED */ @@ -1312,7 +1176,7 @@ signal_command (const char *signum_exp, int from_tty) = strip_bg_char (signum_exp, &async_exec); signum_exp = stripped.get (); - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); if (!signum_exp) error_no_arg (_("signal number")); @@ -1341,19 +1205,19 @@ signal_command (const char *signum_exp, int from_tty) of the wrong thread. */ if (!non_stop) { - struct thread_info *tp; - ptid_t resume_ptid; int must_confirm = 0; /* This indicates what will be resumed. Either a single thread, a whole process, or all threads of all processes. */ - resume_ptid = user_visible_resume_ptid (0); + ptid_t resume_ptid = user_visible_resume_ptid (0); + process_stratum_target *resume_target + = user_visible_resume_target (resume_ptid); + + thread_info *current = inferior_thread (); - ALL_NON_EXITED_THREADS (tp) + for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid)) { - if (ptid_equal (tp->ptid, inferior_ptid)) - continue; - if (!ptid_match (tp->ptid, resume_ptid)) + if (tp == current) continue; if (tp->suspend.stop_signal != GDB_SIGNAL_0 @@ -1433,66 +1297,39 @@ queue_signal_command (const char *signum_exp, int from_tty) /* Data for the FSM that manages the until (with no argument) command. */ -struct until_next_fsm +struct until_next_fsm : public thread_fsm { - /* The base class. */ - struct thread_fsm thread_fsm; - /* The thread that as current when the command was executed. */ int thread; -}; -static int until_next_fsm_should_stop (struct thread_fsm *self, - struct thread_info *thread); -static void until_next_fsm_clean_up (struct thread_fsm *self, - struct thread_info *thread); -static enum async_reply_reason - until_next_fsm_async_reply_reason (struct thread_fsm *self); - -/* until_next_fsm's vtable. */ + until_next_fsm (struct interp *cmd_interp, int thread) + : thread_fsm (cmd_interp), + thread (thread) + { + } -static struct thread_fsm_ops until_next_fsm_ops = -{ - NULL, /* dtor */ - until_next_fsm_clean_up, - until_next_fsm_should_stop, - NULL, /* return_value */ - until_next_fsm_async_reply_reason, + bool should_stop (struct thread_info *thread) override; + void clean_up (struct thread_info *thread) override; + enum async_reply_reason do_async_reply_reason () override; }; -/* Allocate a new until_next_fsm. */ - -static struct until_next_fsm * -new_until_next_fsm (struct interp *cmd_interp, int thread) -{ - struct until_next_fsm *sm; - - sm = XCNEW (struct until_next_fsm); - thread_fsm_ctor (&sm->thread_fsm, &until_next_fsm_ops, cmd_interp); - - sm->thread = thread; - - return sm; -} - /* Implementation of the 'should_stop' FSM method for the until (with no arg) command. */ -static int -until_next_fsm_should_stop (struct thread_fsm *self, - struct thread_info *tp) +bool +until_next_fsm::should_stop (struct thread_info *tp) { if (tp->control.stop_step) - thread_fsm_set_finished (self); + set_finished (); - return 1; + return true; } /* Implementation of the 'clean_up' FSM method for the until (with no arg) command. */ -static void -until_next_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread) +void +until_next_fsm::clean_up (struct thread_info *thread) { delete_longjmp_breakpoint (thread->global_num); } @@ -1500,8 +1337,8 @@ until_next_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread) /* Implementation of the 'async_reply_reason' FSM method for the until (with no arg) command. */ -static enum async_reply_reason -until_next_fsm_async_reply_reason (struct thread_fsm *self) +enum async_reply_reason +until_next_fsm::do_async_reply_reason () { return EXEC_ASYNC_END_STEPPING_RANGE; } @@ -1523,11 +1360,10 @@ until_next_command (int from_tty) struct symtab_and_line sal; struct thread_info *tp = inferior_thread (); int thread = tp->global_num; - struct cleanup *old_chain; struct until_next_fsm *sm; clear_proceed_status (0); - set_step_frame (); + set_step_frame (tp); frame = get_current_frame (); @@ -1554,7 +1390,7 @@ until_next_command (int from_tty) { sal = find_pc_line (pc, 0); - tp->control.step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func)); + tp->control.step_range_start = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func)); tp->control.step_range_end = sal.end; } tp->control.may_range_step = 1; @@ -1562,11 +1398,11 @@ until_next_command (int from_tty) tp->control.step_over_calls = STEP_OVER_ALL; set_longjmp_breakpoint (tp, get_frame_id (frame)); - old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); + delete_longjmp_breakpoint_cleanup lj_deleter (thread); - sm = new_until_next_fsm (command_interp (), tp->global_num); - tp->thread_fsm = &sm->thread_fsm; - discard_cleanups (old_chain); + sm = new until_next_fsm (command_interp (), tp->global_num); + tp->thread_fsm = sm; + lj_deleter.release (); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); } @@ -1585,7 +1421,7 @@ until_command (const char *arg, int from_tty) gdb::unique_xmalloc_ptr stripped = strip_bg_char (arg, &async_exec); arg = stripped.get (); - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); if (arg) until_break_command (arg, from_tty, 0); @@ -1610,7 +1446,7 @@ advance_command (const char *arg, int from_tty) gdb::unique_xmalloc_ptr stripped = strip_bg_char (arg, &async_exec); arg = stripped.get (); - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); until_break_command (arg, from_tty, 1); } @@ -1627,7 +1463,7 @@ get_return_value (struct value *function, struct type *value_type) struct value *value; value_type = check_typedef (value_type); - gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID); + gdb_assert (value_type->code () != TYPE_CODE_VOID); /* FIXME: 2003-09-27: When returning from a nested inferior function call, it's possible (with no help from the architecture vector) @@ -1687,12 +1523,17 @@ print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv) uiout->field_fmt ("gdb-result-var", "$%d", rv->value_history_index); uiout->text (" = "); - get_no_prettyformat_print_options (&opts); - - string_file stb; + get_user_print_options (&opts); - value_print (rv->value, &stb, &opts); - uiout->field_stream ("return-value", stb); + if (opts.finish_print) + { + string_file stb; + value_print (rv->value, &stb, &opts); + uiout->field_stream ("return-value", stb); + } + else + uiout->field_string ("return-value", _(""), + metadata_style.style ()); uiout->text ("\n"); } else @@ -1712,105 +1553,76 @@ print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv) void print_return_value (struct ui_out *uiout, struct return_value_info *rv) { - if (rv->type == NULL || TYPE_CODE (rv->type) == TYPE_CODE_VOID) + if (rv->type == NULL + || check_typedef (rv->type)->code () == TYPE_CODE_VOID) return; - TRY + try { /* print_return_value_1 can throw an exception in some circumstances. We need to catch this so that we still delete the breakpoint. */ print_return_value_1 (uiout, rv); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { exception_print (gdb_stdout, ex); } - END_CATCH } /* Data for the FSM that manages the finish command. */ -struct finish_command_fsm +struct finish_command_fsm : public thread_fsm { - /* The base class. */ - struct thread_fsm thread_fsm; - /* The momentary breakpoint set at the function's return address in the caller. */ - struct breakpoint *breakpoint; + breakpoint_up breakpoint; /* The function that we're stepping out of. */ - struct symbol *function; + struct symbol *function = nullptr; /* If the FSM finishes successfully, this stores the function's return value. */ - struct return_value_info return_value; -}; - -static int finish_command_fsm_should_stop (struct thread_fsm *self, - struct thread_info *thread); -static void finish_command_fsm_clean_up (struct thread_fsm *self, - struct thread_info *thread); -static struct return_value_info * - finish_command_fsm_return_value (struct thread_fsm *self); -static enum async_reply_reason - finish_command_fsm_async_reply_reason (struct thread_fsm *self); - -/* finish_command_fsm's vtable. */ - -static struct thread_fsm_ops finish_command_fsm_ops = -{ - NULL, /* dtor */ - finish_command_fsm_clean_up, - finish_command_fsm_should_stop, - finish_command_fsm_return_value, - finish_command_fsm_async_reply_reason, - NULL, /* should_notify_stop */ -}; - -/* Allocate a new finish_command_fsm. */ + struct return_value_info return_value_info {}; -static struct finish_command_fsm * -new_finish_command_fsm (struct interp *cmd_interp) -{ - struct finish_command_fsm *sm; - - sm = XCNEW (struct finish_command_fsm); - thread_fsm_ctor (&sm->thread_fsm, &finish_command_fsm_ops, cmd_interp); + explicit finish_command_fsm (struct interp *cmd_interp) + : thread_fsm (cmd_interp) + { + } - return sm; -} + bool should_stop (struct thread_info *thread) override; + void clean_up (struct thread_info *thread) override; + struct return_value_info *return_value () override; + enum async_reply_reason do_async_reply_reason () override; +}; /* Implementation of the 'should_stop' FSM method for the finish commands. Detects whether the thread stepped out of the function successfully, and if so, captures the function's return value and marks the FSM finished. */ -static int -finish_command_fsm_should_stop (struct thread_fsm *self, - struct thread_info *tp) +bool +finish_command_fsm::should_stop (struct thread_info *tp) { - struct finish_command_fsm *f = (struct finish_command_fsm *) self; - struct return_value_info *rv = &f->return_value; + struct return_value_info *rv = &return_value_info; - if (f->function != NULL + if (function != NULL && bpstat_find_breakpoint (tp->control.stop_bpstat, - f->breakpoint) != NULL) + breakpoint.get ()) != NULL) { /* We're done. */ - thread_fsm_set_finished (self); + set_finished (); - rv->type = TYPE_TARGET_TYPE (SYMBOL_TYPE (f->function)); + rv->type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); if (rv->type == NULL) internal_error (__FILE__, __LINE__, _("finish_command: function has no target type")); - if (TYPE_CODE (rv->type) != TYPE_CODE_VOID) + if (check_typedef (rv->type)->code () != TYPE_CODE_VOID) { struct value *func; - func = read_var_value (f->function, NULL, get_current_frame ()); + func = read_var_value (function, NULL, get_current_frame ()); rv->value = get_return_value (func, rv->type); if (rv->value != NULL) rv->value_history_index = record_latest_value (rv->value); @@ -1820,45 +1632,36 @@ finish_command_fsm_should_stop (struct thread_fsm *self, { /* Finishing from an inline frame, or reverse finishing. In either case, there's no way to retrieve the return value. */ - thread_fsm_set_finished (self); + set_finished (); } - return 1; + return true; } /* Implementation of the 'clean_up' FSM method for the finish commands. */ -static void -finish_command_fsm_clean_up (struct thread_fsm *self, - struct thread_info *thread) +void +finish_command_fsm::clean_up (struct thread_info *thread) { - struct finish_command_fsm *f = (struct finish_command_fsm *) self; - - if (f->breakpoint != NULL) - { - delete_breakpoint (f->breakpoint); - f->breakpoint = NULL; - } + breakpoint.reset (); delete_longjmp_breakpoint (thread->global_num); } /* Implementation of the 'return_value' FSM method for the finish commands. */ -static struct return_value_info * -finish_command_fsm_return_value (struct thread_fsm *self) +struct return_value_info * +finish_command_fsm::return_value () { - struct finish_command_fsm *f = (struct finish_command_fsm *) self; - - return &f->return_value; + return &return_value_info; } /* Implementation of the 'async_reply_reason' FSM method for the finish commands. */ -static enum async_reply_reason -finish_command_fsm_async_reply_reason (struct thread_fsm *self) +enum async_reply_reason +finish_command_fsm::do_async_reply_reason () { if (execution_direction == EXEC_REVERSE) return EXEC_ASYNC_END_STEPPING_RANGE; @@ -1933,7 +1736,7 @@ finish_forward (struct finish_command_fsm *sm, struct frame_info *frame) sm->breakpoint = set_momentary_breakpoint (gdbarch, sal, get_stack_frame_id (frame), - bp_finish).release (); + bp_finish); /* set_momentary_breakpoint invalidates FRAME. */ frame = NULL; @@ -1990,7 +1793,7 @@ finish_command (const char *arg, int from_tty) gdb::unique_xmalloc_ptr stripped = strip_bg_char (arg, &async_exec); arg = stripped.get (); - prepare_execution_command (¤t_target, async_exec); + prepare_execution_command (current_top_target (), async_exec); if (arg) error (_("The \"finish\" command does not take any arguments.")); @@ -2003,9 +1806,9 @@ finish_command (const char *arg, int from_tty) tp = inferior_thread (); - sm = new_finish_command_fsm (command_interp ()); + sm = new finish_command_fsm (command_interp ()); - tp->thread_fsm = &sm->thread_fsm; + tp->thread_fsm = sm; /* Finishing from an inline frame is completely different. We don't try to show the "return value" - no way to locate it. */ @@ -2017,7 +1820,7 @@ finish_command (const char *arg, int from_tty) called by that frame. We don't use the magic "1" value for step_range_end, because then infrun will think this is nexti, and not step over the rest of this inlined function call. */ - set_step_info (frame, {}); + set_step_info (tp, frame, {}); tp->control.step_range_start = get_frame_pc (frame); tp->control.step_range_end = tp->control.step_range_start; tp->control.step_over_calls = STEP_OVER_ALL; @@ -2049,7 +1852,7 @@ finish_command (const char *arg, int from_tty) if (sm->function != NULL && TYPE_NO_RETURN (sm->function->type) && !query (_("warning: Function %s does not return normally.\n" "Try to finish anyway? "), - SYMBOL_PRINT_NAME (sm->function))) + sm->function->print_name ())) error (_("Not confirmed.")); printf_filtered (_("Run till exit from ")); } @@ -2076,8 +1879,8 @@ info_program_command (const char *args, int from_tty) { bpstat bs; int num, stat; - struct thread_info *tp; ptid_t ptid; + process_stratum_target *proc_target; if (!target_has_execution) { @@ -2086,26 +1889,29 @@ info_program_command (const char *args, int from_tty) } if (non_stop) - ptid = inferior_ptid; - else { - struct target_waitstatus ws; - - get_last_target_status (&ptid, &ws); + ptid = inferior_ptid; + proc_target = current_inferior ()->process_target (); } + else + get_last_target_status (&proc_target, &ptid, nullptr); - if (ptid_equal (ptid, null_ptid) || is_exited (ptid)) + if (ptid == null_ptid || ptid == minus_one_ptid) + error (_("No selected thread.")); + + thread_info *tp = find_thread_ptid (proc_target, ptid); + + if (tp->state == THREAD_EXITED) error (_("Invalid selected thread.")); - else if (is_running (ptid)) + else if (tp->state == THREAD_RUNNING) error (_("Selected thread is running.")); - tp = find_thread_ptid (ptid); bs = tp->control.stop_bpstat; stat = bpstat_num (&bs, &num); target_files_info (); printf_filtered (_("Program stopped at %s.\n"), - paddress (target_gdbarch (), stop_pc)); + paddress (target_gdbarch (), tp->suspend.stop_pc)); if (tp->control.stop_step) printf_filtered (_("It stopped after being stepped.\n")); else if (stat != 0) @@ -2180,7 +1986,7 @@ set_environment_command (const char *arg, int from_tty) if (arg == 0) error_no_arg (_("environment variable and value")); - /* Find seperation between variable name and value. */ + /* Find separation between variable name and value. */ p = (char *) strchr (arg, '='); val = (char *) strchr (arg, ' '); @@ -2277,7 +2083,7 @@ path_command (const char *dirname, int from_tty) current_inferior ()->environment.set (path_var_name, exec_path); xfree (exec_path); if (from_tty) - path_info ((char *) NULL, from_tty); + path_info (NULL, from_tty); } @@ -2318,19 +2124,17 @@ default_print_one_register_info (struct ui_file *file, /* If virtual format is floating, print it that way, and in raw hex. */ - if (TYPE_CODE (regtype) == TYPE_CODE_FLT - || TYPE_CODE (regtype) == TYPE_CODE_DECFLOAT) + if (regtype->code () == TYPE_CODE_FLT + || regtype->code () == TYPE_CODE_DECFLOAT) { struct value_print_options opts; const gdb_byte *valaddr = value_contents_for_printing (val); - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (regtype)); + enum bfd_endian byte_order = type_byte_order (regtype); get_user_print_options (&opts); opts.deref_ref = 1; - val_print (regtype, - value_embedded_offset (val), 0, - &format_stream, 0, val, &opts, current_language); + common_val_print (val, &format_stream, 0, &opts, current_language); if (print_raw_format) { @@ -2348,9 +2152,7 @@ default_print_one_register_info (struct ui_file *file, /* Print the register in hex. */ get_formatted_print_options (&opts, 'x'); opts.deref_ref = 1; - val_print (regtype, - value_embedded_offset (val), 0, - &format_stream, 0, val, &opts, current_language); + common_val_print (val, &format_stream, 0, &opts, current_language); /* If not a vector register, print it also according to its natural format. */ if (print_raw_format && TYPE_VECTOR (regtype) == 0) @@ -2358,9 +2160,7 @@ default_print_one_register_info (struct ui_file *file, pad_to_column (format_stream, value_column_2); get_user_print_options (&opts); opts.deref_ref = 1; - val_print (regtype, - value_embedded_offset (val), 0, - &format_stream, 0, val, &opts, current_language); + common_val_print (val, &format_stream, 0, &opts, current_language); } } @@ -2386,8 +2186,7 @@ default_print_registers_info (struct gdbarch *gdbarch, int regnum, int print_all) { int i; - const int numregs = gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); + const int numregs = gdbarch_num_cooked_regs (gdbarch); for (i = 0; i < numregs; i++) { @@ -2474,8 +2273,7 @@ registers_info (const char *addr_exp, int fpregs) /* User registers lie completely outside of the range of normal registers. Catch them early so that the target never sees them. */ - if (regnum >= gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch)) + if (regnum >= gdbarch_num_cooked_regs (gdbarch)) { struct value *regval = value_of_user_reg (regnum, frame); const char *regname = user_reg_map_regnum_to_name (gdbarch, @@ -2514,8 +2312,7 @@ registers_info (const char *addr_exp, int fpregs) int regnum; for (regnum = 0; - regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); + regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (gdbarch_register_reggroup_p (gdbarch, regnum, group)) @@ -2557,10 +2354,7 @@ print_vector_info (struct ui_file *file, int regnum; int printed_something = 0; - for (regnum = 0; - regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); - regnum++) + for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup)) { @@ -2591,65 +2385,33 @@ kill_command (const char *arg, int from_tty) It should be a distinct flag that indicates that a target is active, cuz some targets don't have processes! */ - if (ptid_equal (inferior_ptid, null_ptid)) + if (inferior_ptid == null_ptid) error (_("The program is not being run.")); if (!query (_("Kill the program being debugged? "))) error (_("Not confirmed.")); - std::string pid_str = target_pid_to_str (inferior_ptid); + int pid = current_inferior ()->pid; + /* Save the pid as a string before killing the inferior, since that + may unpush the current target, and we need the string after. */ + std::string pid_str = target_pid_to_str (ptid_t (pid)); int infnum = current_inferior ()->num; target_kill (); if (print_inferior_events) - printf_unfiltered (_("[Inferior %d (%s) has been killed]\n"), + printf_unfiltered (_("[Inferior %d (%s) killed]\n"), infnum, pid_str.c_str ()); - /* If we still have other inferiors to debug, then don't mess with - with their threads. */ - if (!have_inferiors ()) - { - init_thread_list (); /* Destroy thread info. */ - - /* Killing off the inferior can leave us with a core file. If - so, print the state we are left in. */ - if (target_has_stack) - { - printf_filtered (_("In %s,\n"), target_longname); - print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); - } - } bfd_cache_close_all (); } -/* Used in `attach&' command. ARG is a point to an integer - representing a process id. Proceed threads of this process iff +/* Used in `attach&' command. Proceed threads of inferior INF iff they stopped due to debugger request, and when they did, they - reported a clean stop (GDB_SIGNAL_0). Do not proceed threads - that have been explicitly been told to stop. */ - -static int -proceed_after_attach_callback (struct thread_info *thread, - void *arg) -{ - int pid = * (int *) arg; - - if (ptid_get_pid (thread->ptid) == pid - && !is_exited (thread->ptid) - && !is_executing (thread->ptid) - && !thread->stop_requested - && thread->suspend.stop_signal == GDB_SIGNAL_0) - { - switch_to_thread (thread->ptid); - clear_proceed_status (0); - proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); - } - - return 0; -} + reported a clean stop (GDB_SIGNAL_0). Do not proceed threads that + have been explicitly been told to stop. */ static void -proceed_after_attach (int pid) +proceed_after_attach (inferior *inf) { /* Don't error out if the current thread is running, because there may be other stopped threads. */ @@ -2657,7 +2419,15 @@ proceed_after_attach (int pid) /* Backup current thread and selected frame. */ scoped_restore_current_thread restore_thread; - iterate_over_threads (proceed_after_attach_callback, &pid); + for (thread_info *thread : inf->non_exited_threads ()) + if (!thread->executing + && !thread->stop_requested + && thread->suspend.stop_signal == GDB_SIGNAL_0) + { + switch_to_thread (thread); + clear_proceed_status (0); + proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); + } } /* See inferior.h. */ @@ -2673,7 +2443,7 @@ setup_inferior (int from_tty) /* If no exec file is yet known, try to determine it from the process itself. */ if (get_exec_file (0) == NULL) - exec_file_locate_attach (ptid_get_pid (inferior_ptid), 1, from_tty); + exec_file_locate_attach (inferior_ptid.pid (), 1, from_tty); else { reopen_exec_file (); @@ -2681,9 +2451,9 @@ setup_inferior (int from_tty) } /* Take any necessary post-attaching actions for this platform. */ - target_post_attach (ptid_get_pid (inferior_ptid)); + target_post_attach (inferior_ptid.pid ()); - post_create_inferior (¤t_target, from_tty); + post_create_inferior (current_top_target (), from_tty); } /* What to do after the first program stops after attaching. */ @@ -2724,7 +2494,7 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod already running threads. If a thread has been stopped with a signal, leave it be. */ if (non_stop) - proceed_after_attach (inferior->pid); + proceed_after_attach (inferior); else { if (inferior_thread ()->suspend.stop_signal == GDB_SIGNAL_0) @@ -2747,12 +2517,10 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod Be sure to explicitly stop all threads of the process. This should have no effect on already stopped threads. */ if (non_stop) - target_stop (pid_to_ptid (inferior->pid)); + target_stop (ptid_t (inferior->pid)); else if (target_is_non_stop_p ()) { - struct thread_info *thread; struct thread_info *lowest = inferior_thread (); - int pid = current_inferior ()->pid; stop_all_threads (); @@ -2760,17 +2528,12 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod stop. For consistency, always select the thread with lowest GDB number, which should be the main thread, if it still exists. */ - ALL_NON_EXITED_THREADS (thread) - { - if (ptid_get_pid (thread->ptid) == pid) - { - if (thread->inf->num < lowest->inf->num - || thread->per_inf_num < lowest->per_inf_num) - lowest = thread; - } - } + for (thread_info *thread : current_inferior ()->non_exited_threads ()) + if (thread->inf->num < lowest->inf->num + || thread->per_inf_num < lowest->per_inf_num) + lowest = thread; - switch_to_thread (lowest->ptid); + switch_to_thread (lowest); } /* Tell the user/frontend where we're stopped. */ @@ -2846,10 +2609,10 @@ attach_command (const char *args, int from_tty) prepare_execution_command (attach_target, async_exec); - if (non_stop && !attach_target->to_supports_non_stop (attach_target)) + if (non_stop && !attach_target->supports_non_stop ()) error (_("Cannot attach to this target in non-stop mode")); - attach_target->to_attach (attach_target, args, from_tty); + attach_target->attach (args, from_tty); /* to_attach should push the target, so after this point we shouldn't refer to attach_target again. */ attach_target = NULL; @@ -2893,14 +2656,17 @@ attach_command (const char *args, int from_tty) else /* The user requested an `attach', so stop all threads of this inferior. */ - target_stop (pid_to_ptid (ptid_get_pid (inferior_ptid))); + target_stop (ptid_t (inferior_ptid.pid ())); } + /* Check for exec file mismatch, and let the user solve it. */ + validate_exec_file (from_tty); + mode = async_exec ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_STOP; /* Some system don't generate traps when attaching to inferior. E.g. Mach 3 or GNU hurd. */ - if (!target_attach_no_wait) + if (!target_attach_no_wait ()) { struct attach_command_continuation_args *a; @@ -2919,12 +2685,16 @@ attach_command (const char *args, int from_tty) add_inferior_continuation (attach_command_continuation, a, attach_command_continuation_free_args); + /* Let infrun consider waiting for events out of this + target. */ + inferior->process_target ()->threads_executing = true; + if (!target_is_async_p ()) mark_infrun_async_event_handler (); return; } - - attach_post_wait (args, from_tty, mode); + else + attach_post_wait (args, from_tty, mode); } /* We had just found out that the target was already attached to an @@ -2936,7 +2706,7 @@ attach_command (const char *args, int from_tty) as stopped. */ void -notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) +notice_new_inferior (thread_info *thr, int leave_running, int from_tty) { enum attach_post_wait_mode mode = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING; @@ -2948,12 +2718,12 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) /* Avoid reading registers -- we haven't fetched the target description yet. */ - switch_to_thread_no_regs (find_thread_ptid (ptid)); + switch_to_thread_no_regs (thr); /* When we "notice" a new inferior we need to do all the things we would normally do if we had just attached to it. */ - if (is_executing (inferior_ptid)) + if (thr->executing) { struct attach_command_continuation_args *a; struct inferior *inferior = current_inferior (); @@ -2995,7 +2765,7 @@ detach_command (const char *args, int from_tty) { dont_repeat (); /* Not for the faint of heart. */ - if (ptid_equal (inferior_ptid, null_ptid)) + if (inferior_ptid == null_ptid) error (_("The program is not being run.")); query_if_trace_running (from_tty); @@ -3016,11 +2786,6 @@ detach_command (const char *args, int from_tty) if (!gdbarch_has_global_solist (target_gdbarch ())) no_shared_libraries (NULL, from_tty); - /* If we still have inferiors to debug, then don't mess with their - threads. */ - if (!have_inferiors ()) - init_thread_list (); - if (deprecated_detach_hook) deprecated_detach_hook (); } @@ -3046,20 +2811,15 @@ disconnect_command (const char *args, int from_tty) deprecated_detach_hook (); } -void -interrupt_target_1 (int all_threads) -{ - ptid_t ptid; - - if (all_threads) - ptid = minus_one_ptid; - else - ptid = inferior_ptid; +/* Stop PTID in the current target, and tag the PTID threads as having + been explicitly requested to stop. PTID can be a thread, a + process, or minus_one_ptid, meaning all threads of all inferiors of + the current target. */ - if (non_stop) - target_stop (ptid); - else - target_interrupt (); +static void +stop_current_target_threads_ns (ptid_t ptid) +{ + target_stop (ptid); /* Tag the thread as having been explicitly requested to stop, so other parts of gdb know not to resume this thread automatically, @@ -3067,8 +2827,32 @@ interrupt_target_1 (int all_threads) non-stop mode, as when debugging a multi-threaded application in all-stop mode, we will only get one stop event --- it's undefined which thread will report the event. */ + set_stop_requested (current_inferior ()->process_target (), + ptid, 1); +} + +/* See inferior.h. */ + +void +interrupt_target_1 (bool all_threads) +{ if (non_stop) - set_stop_requested (ptid, 1); + { + if (all_threads) + { + scoped_restore_current_thread restore_thread; + + for (inferior *inf : all_inferiors ()) + { + switch_to_inferior_no_thread (inf); + stop_current_target_threads_ns (minus_one_ptid); + } + } + else + stop_current_target_threads_ns (inferior_ptid); + } + else + target_interrupt (); } /* interrupt [-a] @@ -3106,10 +2890,7 @@ default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, int regnum; int printed_something = 0; - for (regnum = 0; - regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); - regnum++) + for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup)) { @@ -3134,14 +2915,6 @@ info_float_command (const char *args, int from_tty) gdbarch_print_float_info (get_frame_arch (frame), gdb_stdout, frame, args); } -static void -unset_command (const char *args, int from_tty) -{ - printf_filtered (_("\"unset\" must be followed by the " - "name of an unset subcommand.\n")); - help_list (unsetlist, "unset ", all_commands, gdb_stdout); -} - /* Implement `info proc' family of commands. */ static void @@ -3158,7 +2931,7 @@ info_proc_cmd_1 (const char *args, enum info_proc_what what, int from_tty) } } -/* Implement `info proc' when given without any futher parameters. */ +/* Implement `info proc' when given without any further parameters. */ static void info_proc_cmd (const char *args, int from_tty) @@ -3214,6 +2987,14 @@ info_proc_cmd_exe (const char *args, int from_tty) info_proc_cmd_1 (args, IP_EXE, from_tty); } +/* Implement `info proc files'. */ + +static void +info_proc_cmd_files (const char *args, int from_tty) +{ + info_proc_cmd_1 (args, IP_FILES, from_tty); +} + /* Implement `info proc all'. */ static void @@ -3222,6 +3003,19 @@ info_proc_cmd_all (const char *args, int from_tty) info_proc_cmd_1 (args, IP_ALL, from_tty); } +/* Implement `show print finish'. */ + +static void +show_print_finish (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + fprintf_filtered (file, _("\ +Printing of return value after `finish' is %s.\n"), + value); +} + + /* This help string is used for the run, start, and starti commands. It is defined as a macro to prevent duplication. */ @@ -3238,8 +3032,9 @@ use \"set args\" without arguments.\n\ \n\ To start the inferior without using a shell, use \"set startup-with-shell off\"." +void _initialize_infcmd (); void -_initialize_infcmd (void) +_initialize_infcmd () { static struct cmd_list_element *info_proc_cmdlist; struct cmd_list_element *c = NULL; @@ -3259,7 +3054,7 @@ is restored."), cmd_name = "inferior-tty"; c = lookup_cmd (&cmd_name, setlist, "", -1, 1); gdb_assert (c != NULL); - add_alias_cmd ("tty", c, class_alias, 0, &cmdlist); + add_alias_cmd ("tty", c, class_run, 0, &cmdlist); cmd_name = "args"; add_setshow_string_noescape_cmd (cmd_name, class_run, @@ -3300,9 +3095,9 @@ give the program being debugged. With no arguments, prints the entire\n\ environment to be given to the program."), &showlist); set_cmd_completer (c, noop_completer); - add_prefix_cmd ("unset", no_class, unset_command, - _("Complement to certain \"set\" commands."), - &unsetlist, "unset ", 0, &cmdlist); + add_basic_prefix_cmd ("unset", no_class, + _("Complement to certain \"set\" commands."), + &unsetlist, "unset ", 0, &cmdlist); c = add_cmd ("environment", class_run, unset_environment_command, _("\ Cancel environment variable VAR for the program.\n\ @@ -3397,14 +3192,14 @@ Step one instruction exactly.\n\ Usage: stepi [N]\n\ Argument N means step N times (or till program stops for another \ reason).")); - add_com_alias ("si", "stepi", class_alias, 0); + add_com_alias ("si", "stepi", class_run, 0); add_com ("nexti", class_run, nexti_command, _("\ Step one instruction, but proceed through subroutine calls.\n\ Usage: nexti [N]\n\ Argument N means step N times (or till program stops for another \ reason).")); - add_com_alias ("ni", "nexti", class_alias, 0); + add_com_alias ("ni", "nexti", class_run, 0); add_com ("finish", class_run, finish_command, _("\ Execute until selected stack frame returns.\n\ @@ -3428,6 +3223,7 @@ reason).")); add_com_alias ("s", "step", class_run, 1); c = add_com ("until", class_run, until_command, _("\ +Execute until past the current line or past a LOCATION.\n\ Execute until the program reaches a source line greater than the current\n\ or a specified location (same args as break command) within the current \ frame.")); @@ -3442,7 +3238,7 @@ Execution will also stop upon exit from the current stack frame.")); c = add_com ("jump", class_run, jump_command, _("\ Continue program being debugged at specified line or address.\n\ -Usage: jump \n\ +Usage: jump LOCATION\n\ Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\ for an address to start at.")); set_cmd_completer (c, location_completer); @@ -3503,20 +3299,20 @@ in the named register groups.")); _("Execution status of the program.")); add_info ("float", info_float_command, - _("Print the status of the floating point unit\n")); + _("Print the status of the floating point unit.")); add_info ("vector", info_vector_command, - _("Print the status of the vector unit\n")); + _("Print the status of the vector unit.")); add_prefix_cmd ("proc", class_info, info_proc_cmd, _("\ -Show /proc process information about any running process.\n\ +Show additional information about a process.\n\ Specify any process id, or use the program being debugged by default."), &info_proc_cmdlist, "info proc ", 1/*allow-unknown*/, &infolist); add_cmd ("mappings", class_info, info_proc_cmd_mappings, _("\ -List of mapped memory regions."), +List memory regions mapped by the specified process."), &info_proc_cmdlist); add_cmd ("stat", class_info, info_proc_cmd_stat, _("\ @@ -3528,18 +3324,30 @@ List process info from /proc/PID/status."), &info_proc_cmdlist); add_cmd ("cwd", class_info, info_proc_cmd_cwd, _("\ -List current working directory of the process."), +List current working directory of the specified process."), &info_proc_cmdlist); add_cmd ("cmdline", class_info, info_proc_cmd_cmdline, _("\ -List command line arguments of the process."), +List command line arguments of the specified process."), &info_proc_cmdlist); add_cmd ("exe", class_info, info_proc_cmd_exe, _("\ -List absolute filename for executable of the process."), +List absolute filename for executable of the specified process."), + &info_proc_cmdlist); + + add_cmd ("files", class_info, info_proc_cmd_files, _("\ +List files opened by the specified process."), &info_proc_cmdlist); add_cmd ("all", class_info, info_proc_cmd_all, _("\ -List all available /proc info."), +List all available info about the specified process."), &info_proc_cmdlist); + + add_setshow_boolean_cmd ("finish", class_support, + &user_print_options.finish_print, _("\ +Set whether `finish' prints the return value."), _("\ +Show whether `finish' prints the return value."), NULL, + NULL, + show_print_finish, + &setprintlist, &showprintlist); }