X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finfcmd.c;h=5aa6b00f20f3da8681a0c736d2b7df85996d6c26;hb=4efeb0d3e8ee210cd61b15355cca39b16b66004d;hp=eb18efab513bf9c917a9b25bd5d640f15e9b96f6;hpb=34877895ca38f74ae31bd65a6916560020d9d62b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcmd.c b/gdb/infcmd.c index eb18efab51..5aa6b00f20 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-2019 Free Software Foundation, Inc. + Copyright (C) 1986-2021 Free Software Foundation, Inc. This file is part of GDB. @@ -47,11 +47,11 @@ #include "inline-frame.h" #include "tracepoint.h" #include "inf-loop.h" -#include "continuations.h" #include "linespec.h" #include "thread-fsm.h" #include "top.h" #include "interps.h" +#include "skip.h" #include "gdbsupport/gdb_optional.h" #include "source.h" #include "cli/cli-style.h" @@ -63,7 +63,7 @@ static void until_next_command (int); static void step_1 (int, int, const char *); #define ERROR_NO_INFERIOR \ - if (!target_has_execution) error (_("The program is not being run.")); + if (!target_has_execution ()) error (_("The program is not being run.")); /* Scratch area where string containing arguments to give to the program will be stored by 'set args'. As soon as anything is @@ -99,27 +99,6 @@ enum stop_stack_kind stop_stack_dummy; int stopped_by_random_signal; -/* Accessor routines. */ - -/* Set the io terminal for the current inferior. Ownership of - TERMINAL_NAME is not transferred. */ - -void -set_inferior_io_terminal (const char *terminal_name) -{ - xfree (current_inferior ()->terminal); - - if (terminal_name != NULL && *terminal_name != '\0') - current_inferior ()->terminal = xstrdup (terminal_name); - else - current_inferior ()->terminal = NULL; -} - -const char * -get_inferior_io_terminal (void) -{ - return current_inferior ()->terminal; -} static void set_inferior_tty_command (const char *args, int from_tty, @@ -127,7 +106,7 @@ set_inferior_tty_command (const char *args, int from_tty, { /* CLI has assigned the user-provided value to inferior_io_terminal_scratch. Now route it to current inferior. */ - set_inferior_io_terminal (inferior_io_terminal_scratch); + current_inferior ()->set_tty (inferior_io_terminal_scratch); } static void @@ -136,13 +115,13 @@ show_inferior_tty_command (struct ui_file *file, int from_tty, { /* Note that we ignore the passed-in value in favor of computing it directly. */ - const char *inferior_io_terminal = get_inferior_io_terminal (); + const char *inferior_tty = current_inferior ()->tty (); - if (inferior_io_terminal == NULL) - inferior_io_terminal = ""; + if (inferior_tty == nullptr) + inferior_tty = ""; fprintf_filtered (gdb_stdout, _("Terminal for future runs of program being debugged " - "is \"%s\".\n"), inferior_io_terminal); + "is \"%s\".\n"), inferior_tty); } const char * @@ -150,12 +129,10 @@ 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) @@ -258,125 +235,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 @@ -420,7 +278,7 @@ strip_bg_char (const char *args, int *bg_char_p) should be stopped. */ void -post_create_inferior (struct target_ops *target, int from_tty) +post_create_inferior (int from_tty) { /* Be sure we own the terminal in case write operations are performed. */ @@ -440,7 +298,8 @@ post_create_inferior (struct target_ops *target, int from_tty) thr->suspend.stop_pc = 0; try { - thr->suspend.stop_pc = regcache_read_pc (get_current_regcache ()); + regcache *rc = get_thread_regcache (thr); + thr->suspend.stop_pc = regcache_read_pc (rc); } catch (const gdb_exception_error &ex) { @@ -448,7 +307,7 @@ post_create_inferior (struct target_ops *target, int from_tty) throw; } - if (exec_bfd) + if (current_program_space->exec_bfd ()) { const unsigned solib_add_generation = current_program_space->solib_add_generation; @@ -487,7 +346,7 @@ post_create_inferior (struct target_ops *target, int from_tty) if the now pushed target supports hardware watchpoints. */ breakpoint_re_set (); - gdb::observers::inferior_created.notify (target, from_tty); + gdb::observers::inferior_created.notify (current_inferior ()); } /* Kill the inferior if already running. This function is designed @@ -498,7 +357,7 @@ post_create_inferior (struct target_ops *target, int from_tty) static void kill_if_already_running (int from_tty) { - if (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. */ @@ -559,6 +418,8 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how) dont_repeat (); + scoped_disable_commit_resumed disable_commit_resumed ("running"); + kill_if_already_running (from_tty); init_wait_for_inferior (); @@ -644,14 +505,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 (current_top_target (), 0); + post_create_inferior (0); /* Queue a pending event so that the program stops immediately. */ if (run_how == RUN_STOP_AT_FIRST_INSN) @@ -669,6 +539,8 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how) /* Since there was no error, there's no need to finish the thread states here. */ finish_state.release (); + + disable_commit_resumed.reset_and_commit (); } static void @@ -717,6 +589,9 @@ proceed_thread_callback (struct thread_info *thread, void *arg) if (thread->state != THREAD_STOPPED) return 0; + if (!thread->inf->has_execution ()) + return 0; + switch_to_thread (thread); clear_proceed_status (0); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); @@ -810,7 +685,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; @@ -822,17 +697,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.")); @@ -849,11 +724,11 @@ continue_command (const char *args, int from_tty) 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; @@ -881,32 +756,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 (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->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); } @@ -983,7 +861,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) @@ -1002,7 +880,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 (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->top_target (), async_exec); count = count_string ? parse_and_eval_long (count_string) : 1; @@ -1021,7 +899,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 { @@ -1032,7 +910,7 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string) thr->thread_fsm->clean_up (thr); proceeded = normal_stop (); if (!proceeded) - inferior_event_handler (INF_EXEC_COMPLETE, NULL); + inferior_event_handler (INF_EXEC_COMPLETE); all_uis_check_sync_execution_done (); } } @@ -1051,7 +929,7 @@ step_command_fsm::should_stop (struct thread_info *tp) /* There are more steps to make, and we did stop due to ending a stepping range. Do another step. */ if (--count > 0) - return prepare_one_step (this); + return prepare_one_step (tp, this); set_finished (); } @@ -1083,19 +961,17 @@ step_command_fsm::do_async_reply_reason () 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) { @@ -1106,14 +982,29 @@ prepare_one_step (struct step_command_fsm *sm) && 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); - 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); @@ -1121,6 +1012,20 @@ prepare_one_step (struct step_command_fsm *sm) &tp->control.step_range_start, &tp->control.step_range_end); + /* There's a problem in gcc (PR gcc/98780) that causes missing line + table entries, which results in a too large stepping range. + Use inlined_subroutine info to make the range more narrow. */ + if (inline_skipped_frames (tp) > 0) + { + symbol *sym = inline_skipped_symbol (tp); + if (SYMBOL_CLASS (sym) == LOC_BLOCK) + { + const block *block = SYMBOL_BLOCK_VALUE (sym); + if (BLOCK_END (block) < tp->control.step_range_end) + tp->control.step_range_end = BLOCK_END (block); + } + } + tp->control.may_range_step = 1; /* If we have no line info, switch to stepi mode. */ @@ -1187,7 +1092,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 (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->top_target (), async_exec); if (!arg) error_no_arg (_("starting address")); @@ -1210,7 +1115,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 */ @@ -1222,7 +1127,7 @@ jump_command (const char *arg, int from_tty) struct obj_section *section; fixup_symbol_section (sfn, 0); - section = SYMBOL_OBJ_SECTION (symbol_objfile (sfn), sfn); + section = sfn->obj_section (symbol_objfile (sfn)); if (section_is_overlay (section) && !section_is_mapped (section)) { @@ -1267,7 +1172,7 @@ signal_command (const char *signum_exp, int from_tty) = strip_bg_char (signum_exp, &async_exec); signum_exp = stripped.get (); - prepare_execution_command (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->top_target (), async_exec); if (!signum_exp) error_no_arg (_("signal number")); @@ -1301,10 +1206,14 @@ signal_command (const char *signum_exp, int from_tty) /* This indicates what will be resumed. Either a single thread, a whole process, or all threads of all processes. */ ptid_t resume_ptid = user_visible_resume_ptid (0); + process_stratum_target *resume_target + = user_visible_resume_target (resume_ptid); - for (thread_info *tp : all_non_exited_threads (resume_ptid)) + thread_info *current = inferior_thread (); + + for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid)) { - if (tp->ptid == inferior_ptid) + if (tp == current) continue; if (tp->suspend.stop_signal != GDB_SIGNAL_0 @@ -1450,7 +1359,7 @@ until_next_command (int from_tty) struct until_next_fsm *sm; clear_proceed_status (0); - set_step_frame (); + set_step_frame (tp); frame = get_current_frame (); @@ -1508,7 +1417,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 (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->top_target (), async_exec); if (arg) until_break_command (arg, from_tty, 0); @@ -1533,7 +1442,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 (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->top_target (), async_exec); until_break_command (arg, from_tty, 1); } @@ -1550,7 +1459,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) @@ -1641,7 +1550,7 @@ void print_return_value (struct ui_out *uiout, struct return_value_info *rv) { if (rv->type == NULL - || TYPE_CODE (check_typedef (rv->type)) == TYPE_CODE_VOID) + || check_typedef (rv->type)->code () == TYPE_CODE_VOID) return; try @@ -1705,7 +1614,7 @@ finish_command_fsm::should_stop (struct thread_info *tp) internal_error (__FILE__, __LINE__, _("finish_command: function has no target type")); - if (TYPE_CODE (check_typedef (rv->type)) != TYPE_CODE_VOID) + if (check_typedef (rv->type)->code () != TYPE_CODE_VOID) { struct value *func; @@ -1880,7 +1789,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 (current_top_target (), async_exec); + prepare_execution_command (current_inferior ()->top_target (), async_exec); if (arg) error (_("The \"finish\" command does not take any arguments.")); @@ -1907,7 +1816,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; @@ -1939,7 +1848,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 ")); } @@ -1967,26 +1876,26 @@ info_program_command (const char *args, int from_tty) bpstat bs; int num, stat; ptid_t ptid; + process_stratum_target *proc_target; - if (!target_has_execution) + if (!target_has_execution ()) { printf_filtered (_("The program being debugged is not being run.\n")); return; } 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 == null_ptid || ptid == minus_one_ptid) error (_("No selected thread.")); - thread_info *tp = find_thread_ptid (ptid); + thread_info *tp = find_thread_ptid (proc_target, ptid); if (tp->state == THREAD_EXITED) error (_("Invalid selected thread.")); @@ -2004,7 +1913,7 @@ info_program_command (const char *args, int from_tty) else if (stat != 0) { /* There may be several breakpoints in the same place, so this - isn't as strange as it seems. */ + isn't as strange as it seems. */ while (stat != 0) { if (stat < 0) @@ -2080,14 +1989,14 @@ set_environment_command (const char *arg, int from_tty) if (p != 0 && val != 0) { /* We have both a space and an equals. If the space is before the - equals, walk forward over the spaces til we see a nonspace - (possibly the equals). */ + equals, walk forward over the spaces til we see a nonspace + (possibly the equals). */ if (p > val) while (*val == ' ') val++; /* Now if the = is after the char following the spaces, - take the char following the spaces. */ + take the char following the spaces. */ if (p > val) p = val - 1; } @@ -2132,7 +2041,7 @@ unset_environment_command (const char *var, int from_tty) if (var == 0) { /* If there is no argument, delete all environment variables. - Ask for confirmation if reading from the terminal. */ + Ask for confirmation if reading from the terminal. */ if (!from_tty || query (_("Delete all environment variables? "))) current_inferior ()->environment.clear (); } @@ -2199,7 +2108,7 @@ default_print_one_register_info (struct ui_file *file, { value_column_1 = 15, /* Give enough room for "0x", 16 hex digits and two spaces in - preceding column. */ + preceding column. */ value_column_2 = value_column_1 + 2 + 16 + 2, }; @@ -2211,8 +2120,8 @@ 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); @@ -2221,9 +2130,7 @@ default_print_one_register_info (struct ui_file *file, 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) { @@ -2241,19 +2148,15 @@ 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) + if (print_raw_format && regtype->is_vector () == 0) { 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); } } @@ -2284,7 +2187,7 @@ default_print_registers_info (struct gdbarch *gdbarch, for (i = 0; i < numregs; i++) { /* Decide between printing all regs, non-float / vector regs, or - specific reg. */ + specific reg. */ if (regnum == -1) { if (print_all) @@ -2305,7 +2208,7 @@ default_print_registers_info (struct gdbarch *gdbarch, } /* If the register name is empty, it is undefined for this - processor, so don't display anything. */ + processor, so don't display anything. */ if (gdbarch_register_name (gdbarch, i) == NULL || *(gdbarch_register_name (gdbarch, i)) == '\0') continue; @@ -2322,7 +2225,7 @@ registers_info (const char *addr_exp, int fpregs) struct frame_info *frame; struct gdbarch *gdbarch; - if (!target_has_registers) + if (!target_has_registers ()) error (_("The program has no registers now.")); frame = get_selected_frame (NULL); gdbarch = get_frame_arch (frame); @@ -2343,7 +2246,7 @@ registers_info (const char *addr_exp, int fpregs) addr_exp = skip_spaces (addr_exp); /* Discard any leading ``$''. Check that there is something - resembling a register following it. */ + resembling a register following it. */ if (addr_exp[0] == '$') addr_exp++; if (isspace ((*addr_exp)) || (*addr_exp) == '\0') @@ -2463,7 +2366,7 @@ print_vector_info (struct ui_file *file, static void info_vector_command (const char *args, int from_tty) { - if (!target_has_registers) + if (!target_has_registers ()) error (_("The program has no registers now.")); print_vector_info (gdb_stdout, get_selected_frame (NULL), args); @@ -2495,20 +2398,6 @@ kill_command (const char *arg, int from_tty) 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 (); } @@ -2560,7 +2449,7 @@ setup_inferior (int from_tty) /* Take any necessary post-attaching actions for this platform. */ target_post_attach (inferior_ptid.pid ()); - post_create_inferior (current_top_target (), from_tty); + post_create_inferior (from_tty); } /* What to do after the first program stops after attaching. */ @@ -2577,11 +2466,11 @@ enum attach_post_wait_mode }; /* Called after we've attached to a process and we've seen it stop for - the first time. If ASYNC_EXEC is true, re-resume threads that - should be running. Else if ATTACH, */ + the first time. Resume, stop, or don't touch the threads according + to MODE. */ static void -attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mode) +attach_post_wait (int from_tty, enum attach_post_wait_mode mode) { struct inferior *inferior; @@ -2596,7 +2485,7 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod /* The user requested an `attach&', so be sure to leave threads that didn't get a signal running. */ - /* Immediatelly resume all suspended threads of this inferior, + /* Immediately resume all suspended threads of this inferior, and this inferior only. This should have no effect on already running threads. If a thread has been stopped with a signal, leave it be. */ @@ -2650,35 +2539,6 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod } } -struct attach_command_continuation_args -{ - char *args; - int from_tty; - enum attach_post_wait_mode mode; -}; - -static void -attach_command_continuation (void *args, int err) -{ - struct attach_command_continuation_args *a - = (struct attach_command_continuation_args *) args; - - if (err) - return; - - attach_post_wait (a->args, a->from_tty, a->mode); -} - -static void -attach_command_continuation_free_args (void *args) -{ - struct attach_command_continuation_args *a - = (struct attach_command_continuation_args *) args; - - xfree (a->args); - xfree (a); -} - /* "attach" command entry point. Takes a program started up outside of gdb and ``attaches'' to it. This stops it cold in its tracks and allows us to start debugging it. */ @@ -2693,11 +2553,13 @@ attach_command (const char *args, int from_tty) dont_repeat (); /* Not for the faint of heart */ + scoped_disable_commit_resumed disable_commit_resumed ("attaching"); + if (gdbarch_has_global_solist (target_gdbarch ())) /* Don't complain if all processes share the same symbol space. */ ; - else if (target_has_execution) + else if (target_has_execution ()) { if (query (_("A program is being debugged already. Kill it? "))) target_kill (); @@ -2747,7 +2609,6 @@ attach_command (const char *args, int from_tty) /* Set up execution context to know that we should return from wait_for_inferior as soon as the target reports a stop. */ init_wait_for_inferior (); - clear_proceed_status (0); inferior->needs_setup = 1; @@ -2766,14 +2627,15 @@ attach_command (const char *args, int from_tty) 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 ()) { - struct attach_command_continuation_args *a; - /* Careful here. See comments in inferior.h. Basically some OSes don't ignore SIGSTOPs on continue requests anymore. We need a way for handle_inferior_event to reset the stop_signal @@ -2782,19 +2644,23 @@ attach_command (const char *args, int from_tty) inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP; /* Wait for stop. */ - a = XNEW (struct attach_command_continuation_args); - a->args = xstrdup (args); - a->from_tty = from_tty; - a->mode = mode; - add_inferior_continuation (attach_command_continuation, a, - attach_command_continuation_free_args); + inferior->add_continuation ([=] () + { + attach_post_wait (from_tty, mode); + }); + + /* 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; } + else + attach_post_wait (from_tty, mode); - attach_post_wait (args, from_tty, mode); + disable_commit_resumed.reset_and_commit (); } /* We had just found out that the target was already attached to an @@ -2825,7 +2691,6 @@ notice_new_inferior (thread_info *thr, int leave_running, int from_tty) if (thr->executing) { - struct attach_command_continuation_args *a; struct inferior *inferior = current_inferior (); /* We're going to install breakpoints, and poke at memory, @@ -2836,17 +2701,15 @@ notice_new_inferior (thread_info *thr, int leave_running, int from_tty) inferior->control.stop_soon = STOP_QUIETLY_REMOTE; /* Wait for stop before proceeding. */ - a = XNEW (struct attach_command_continuation_args); - a->args = xstrdup (""); - a->from_tty = from_tty; - a->mode = mode; - add_inferior_continuation (attach_command_continuation, a, - attach_command_continuation_free_args); + inferior->add_continuation ([=] () + { + attach_post_wait (from_tty, mode); + }); return; } - attach_post_wait ("" /* args */, from_tty, mode); + attach_post_wait (from_tty, mode); } /* @@ -2868,10 +2731,22 @@ detach_command (const char *args, int from_tty) if (inferior_ptid == null_ptid) error (_("The program is not being run.")); + scoped_disable_commit_resumed disable_commit_resumed ("detaching"); + query_if_trace_running (from_tty); disconnect_tracing (); + /* Hold a strong reference to the target while (maybe) + detaching the parent. Otherwise detaching could close the + target. */ + auto target_ref + = target_ops_ref::new_reference (current_inferior ()->process_target ()); + + /* Save this before detaching, since detaching may unpush the + process_stratum target. */ + bool was_non_stop_p = target_is_non_stop_p (); + target_detach (current_inferior (), from_tty); /* The current inferior process was just detached successfully. Get @@ -2888,6 +2763,11 @@ detach_command (const char *args, int from_tty) if (deprecated_detach_hook) deprecated_detach_hook (); + + if (!was_non_stop_p) + restart_after_all_stop_detach (as_process_stratum_target (target_ref.get ())); + + disable_commit_resumed.reset_and_commit (); } /* Disconnect from the current target without resuming it (leaving it @@ -2911,20 +2791,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, @@ -2932,8 +2807,36 @@ 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) +{ + scoped_disable_commit_resumed disable_commit_resumed ("interrupting"); + 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 (); + + disable_commit_resumed.reset_and_commit (); } /* interrupt [-a] @@ -2989,21 +2892,13 @@ info_float_command (const char *args, int from_tty) { struct frame_info *frame; - if (!target_has_registers) + if (!target_has_registers ()) error (_("The program has no registers now.")); frame = get_selected_frame (NULL); 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 @@ -3121,8 +3016,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; @@ -3140,9 +3036,9 @@ is restored."), show_inferior_tty_command, &setlist, &showlist); cmd_name = "inferior-tty"; - c = lookup_cmd (&cmd_name, setlist, "", -1, 1); + c = lookup_cmd (&cmd_name, setlist, "", NULL, -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, @@ -3153,7 +3049,7 @@ Follow this command with any number of args, to be passed to the program."), set_args_command, show_args_command, &setlist, &showlist); - c = lookup_cmd (&cmd_name, setlist, "", -1, 1); + c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1); gdb_assert (c != NULL); set_cmd_completer (c, filename_completer); @@ -3172,7 +3068,7 @@ working directory."), set_cwd_command, show_cwd_command, &setlist, &showlist); - c = lookup_cmd (&cmd_name, setlist, "", -1, 1); + c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1); gdb_assert (c != NULL); set_cmd_completer (c, filename_completer); @@ -3183,9 +3079,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\ @@ -3280,14 +3176,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\