X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finfcmd.c;h=58ba1cb8d01cdb4b6cc30f90ee6bc0c1de91499d;hb=5077bfff905136e9d9a8fdf0886f6217887622ad;hp=98c386ac6322ed1b79bea5f336fd4ae072ac8b4d;hpb=cfc3163382898a537c742bee1bf8240b3c09df35;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 98c386ac63..58ba1cb8d0 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-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -56,6 +56,8 @@ #include "cli/cli-utils.h" #include "infcall.h" #include "thread-fsm.h" +#include "top.h" +#include "interps.h" /* Local functions: */ @@ -406,7 +408,7 @@ post_create_inferior (struct target_ops *target, int from_tty) { /* Be sure we own the terminal in case write operations are performed. */ - target_terminal_ours (); + target_terminal_ours_for_output (); /* If the target hasn't taken care of this already, do it now. Targets which need to access registers during to_open, @@ -509,7 +511,7 @@ prepare_execution_command (struct target_ops *target, int background) simulate synchronous (fg) execution. Note no cleanup is necessary for this. stdin is re-enabled whenever an error reaches the top level. */ - async_disable_stdin (); + all_uis_on_sync_execution_starting (); } } @@ -730,7 +732,7 @@ continue_1 (int all_threads) iterate_over_threads (proceed_thread_callback, NULL); - if (sync_execution) + if (current_ui->prompt_state == PROMPT_BLOCKED) { /* If all threads in the target were already running, proceed_thread_callback ends up never calling proceed, @@ -775,8 +777,6 @@ continue_command (char *args, int from_tty) args = strip_bg_char (args, &async_exec); args_chain = make_cleanup (xfree, args); - prepare_execution_command (¤t_target, async_exec); - if (args != NULL) { if (startswith (args, "-a")) @@ -840,6 +840,17 @@ continue_command (char *args, int from_tty) /* Done with ARGS. */ do_cleanups (args_chain); + ERROR_NO_INFERIOR; + ensure_not_tfind_mode (); + + if (!non_stop || !all_threads) + { + ensure_valid_thread (); + ensure_not_running (); + } + + prepare_execution_command (¤t_target, async_exec); + if (from_tty) printf_filtered (_("Continuing.\n")); @@ -915,13 +926,12 @@ struct step_command_fsm /* If true, this is a stepi/nexti, otherwise a step/step. */ int single_inst; - - /* The thread that the command was run on. */ - int thread; }; -static void step_command_fsm_clean_up (struct thread_fsm *self); -static int step_command_fsm_should_stop (struct thread_fsm *self); +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); @@ -939,12 +949,12 @@ static struct thread_fsm_ops step_command_fsm_ops = /* Allocate a new step_command_fsm. */ static struct step_command_fsm * -new_step_command_fsm (void) +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); + thread_fsm_ctor (&sm->thread_fsm, &step_command_fsm_ops, cmd_interp); return sm; } @@ -960,7 +970,6 @@ step_command_fsm_prepare (struct step_command_fsm *sm, sm->skip_subroutines = skip_subroutines; sm->single_inst = single_inst; sm->count = count; - sm->thread = thread->num; /* Leave the si command alone. */ if (!sm->single_inst || sm->skip_subroutines) @@ -1000,7 +1009,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) /* Setup the execution command state machine to handle all the COUNT steps. */ thr = inferior_thread (); - step_sm = new_step_command_fsm (); + step_sm = new_step_command_fsm (command_interp ()); thr->thread_fsm = &step_sm->thread_fsm; step_command_fsm_prepare (step_sm, skip_subroutines, @@ -1014,11 +1023,15 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); else { + int proceeded; + /* Stepped into an inline frame. Pretend that we've stopped. */ - thread_fsm_clean_up (thr->thread_fsm); - normal_stop (); - inferior_event_handler (INF_EXEC_COMPLETE, NULL); + thread_fsm_clean_up (thr->thread_fsm, thr); + proceeded = normal_stop (); + if (!proceeded) + inferior_event_handler (INF_EXEC_COMPLETE, NULL); + all_uis_check_sync_execution_done (); } } @@ -1029,10 +1042,9 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) will need to keep going. */ static int -step_command_fsm_should_stop (struct thread_fsm *self) +step_command_fsm_should_stop (struct thread_fsm *self, struct thread_info *tp) { struct step_command_fsm *sm = (struct step_command_fsm *) self; - struct thread_info *tp = find_thread_id (sm->thread); if (tp->control.stop_step) { @@ -1050,12 +1062,12 @@ step_command_fsm_should_stop (struct thread_fsm *self) /* Implementation of the 'clean_up' FSM method for stepping commands. */ static void -step_command_fsm_clean_up (struct thread_fsm *self) +step_command_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread) { struct step_command_fsm *sm = (struct step_command_fsm *) self; if (!sm->single_inst || sm->skip_subroutines) - delete_longjmp_breakpoint (sm->thread); + delete_longjmp_breakpoint (thread->global_num); } /* Implementation of the 'async_reply_reason' FSM method for stepping @@ -1128,7 +1140,7 @@ prepare_one_step (struct step_command_fsm *sm) &tp->control.step_range_end) == 0) error (_("Cannot find bounds of current function")); - target_terminal_ours (); + target_terminal_ours_for_output (); printf_filtered (_("Single stepping until exit from function %s," "\nwhich has no line number information.\n"), name); @@ -1316,8 +1328,8 @@ signal_command (char *signum_exp, int from_tty) { if (!must_confirm) printf_unfiltered (_("Note:\n")); - printf_unfiltered (_(" Thread %d previously stopped with signal %s, %s.\n"), - tp->num, + printf_unfiltered (_(" Thread %s previously stopped with signal %s, %s.\n"), + print_thread_id (tp), gdb_signal_to_name (tp->suspend.stop_signal), gdb_signal_to_string (tp->suspend.stop_signal)); must_confirm = 1; @@ -1325,10 +1337,10 @@ signal_command (char *signum_exp, int from_tty) } if (must_confirm - && !query (_("Continuing thread %d (the current thread) with specified signal will\n" + && !query (_("Continuing thread %s (the current thread) with specified signal will\n" "still deliver the signals noted above to their respective threads.\n" "Continue anyway? "), - inferior_thread ()->num)) + print_thread_id (inferior_thread ()))) error (_("Not confirmed.")); } @@ -1397,8 +1409,10 @@ struct until_next_fsm int thread; }; -static int until_next_fsm_should_stop (struct thread_fsm *self); -static void until_next_fsm_clean_up (struct thread_fsm *self); +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); @@ -1416,12 +1430,12 @@ static struct thread_fsm_ops until_next_fsm_ops = /* Allocate a new until_next_fsm. */ static struct until_next_fsm * -new_until_next_fsm (int thread) +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); + thread_fsm_ctor (&sm->thread_fsm, &until_next_fsm_ops, cmd_interp); sm->thread = thread; @@ -1432,10 +1446,9 @@ new_until_next_fsm (int thread) no arg) command. */ static int -until_next_fsm_should_stop (struct thread_fsm *self) +until_next_fsm_should_stop (struct thread_fsm *self, + struct thread_info *tp) { - struct thread_info *tp = inferior_thread (); - if (tp->control.stop_step) thread_fsm_set_finished (self); @@ -1446,11 +1459,11 @@ until_next_fsm_should_stop (struct thread_fsm *self) arg) command. */ static void -until_next_fsm_clean_up (struct thread_fsm *self) +until_next_fsm_clean_up (struct thread_fsm *self, struct thread_info *thread) { struct until_next_fsm *sm = (struct until_next_fsm *) self; - delete_longjmp_breakpoint (sm->thread); + delete_longjmp_breakpoint (thread->global_num); } /* Implementation of the 'async_reply_reason' FSM method for the until @@ -1478,7 +1491,7 @@ until_next_command (int from_tty) struct symbol *func; struct symtab_and_line sal; struct thread_info *tp = inferior_thread (); - int thread = tp->num; + int thread = tp->global_num; struct cleanup *old_chain; struct until_next_fsm *sm; @@ -1520,12 +1533,11 @@ until_next_command (int from_tty) set_longjmp_breakpoint (tp, get_frame_id (frame)); old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); - sm = new_until_next_fsm (tp->num); + sm = new_until_next_fsm (command_interp (), tp->global_num); tp->thread_fsm = &sm->thread_fsm; discard_cleanups (old_chain); proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); - } static void @@ -1585,22 +1597,15 @@ advance_command (char *arg, int from_tty) right after an inferior call has finished. */ struct value * -get_return_value (struct value *function, struct type *value_type, - struct dummy_frame_context_saver *ctx_saver) +get_return_value (struct value *function, struct type *value_type) { - struct regcache *stop_regs = NULL; + struct regcache *stop_regs; struct gdbarch *gdbarch; struct value *value; - struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); + struct cleanup *cleanup; - /* If registers were not saved, use the current registers. */ - if (ctx_saver != NULL) - stop_regs = dummy_frame_context_saver_get_regs (ctx_saver); - else - { - stop_regs = regcache_dup (get_current_regcache ()); - make_cleanup_regcache_xfree (stop_regs); - } + stop_regs = regcache_dup (get_current_regcache ()); + cleanup = make_cleanup_regcache_xfree (stop_regs); gdbarch = get_regcache_arch (stop_regs); @@ -1723,9 +1728,6 @@ struct finish_command_fsm /* The base class. */ struct thread_fsm thread_fsm; - /* The thread that was current when the command was executed. */ - int thread; - /* The momentary breakpoint set at the function's return address in the caller. */ struct breakpoint *breakpoint; @@ -1738,8 +1740,10 @@ struct finish_command_fsm struct return_value_info return_value; }; -static int finish_command_fsm_should_stop (struct thread_fsm *self); -static void finish_command_fsm_clean_up (struct thread_fsm *self); +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 @@ -1754,19 +1758,18 @@ static struct thread_fsm_ops finish_command_fsm_ops = 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. */ static struct finish_command_fsm * -new_finish_command_fsm (int thread) +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); - - sm->thread = thread; + thread_fsm_ctor (&sm->thread_fsm, &finish_command_fsm_ops, cmd_interp); return sm; } @@ -1777,11 +1780,11 @@ new_finish_command_fsm (int thread) marks the FSM finished. */ static int -finish_command_fsm_should_stop (struct thread_fsm *self) +finish_command_fsm_should_stop (struct thread_fsm *self, + struct thread_info *tp) { struct finish_command_fsm *f = (struct finish_command_fsm *) self; struct return_value_info *rv = &f->return_value; - struct thread_info *tp = find_thread_id (f->thread); if (f->function != NULL && bpstat_find_breakpoint (tp->control.stop_bpstat, @@ -1800,8 +1803,9 @@ finish_command_fsm_should_stop (struct thread_fsm *self) struct value *func; func = read_var_value (f->function, NULL, get_current_frame ()); - rv->value = get_return_value (func, rv->type, NULL); - rv->value_history_index = record_latest_value (rv->value); + rv->value = get_return_value (func, rv->type); + if (rv->value != NULL) + rv->value_history_index = record_latest_value (rv->value); } } else if (tp->control.stop_step) @@ -1818,7 +1822,8 @@ finish_command_fsm_should_stop (struct thread_fsm *self) commands. */ static void -finish_command_fsm_clean_up (struct thread_fsm *self) +finish_command_fsm_clean_up (struct thread_fsm *self, + struct thread_info *thread) { struct finish_command_fsm *f = (struct finish_command_fsm *) self; @@ -1827,7 +1832,7 @@ finish_command_fsm_clean_up (struct thread_fsm *self) delete_breakpoint (f->breakpoint); f->breakpoint = NULL; } - delete_longjmp_breakpoint (f->thread); + delete_longjmp_breakpoint (thread->global_num); } /* Implementation of the 'return_value' FSM method for the finish @@ -1847,8 +1852,6 @@ finish_command_fsm_return_value (struct thread_fsm *self) static enum async_reply_reason finish_command_fsm_async_reply_reason (struct thread_fsm *self) { - struct finish_command_fsm *f = (struct finish_command_fsm *) self; - if (execution_direction == EXEC_REVERSE) return EXEC_ASYNC_END_STEPPING_RANGE; else @@ -1936,6 +1939,30 @@ finish_forward (struct finish_command_fsm *sm, struct frame_info *frame) proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT); } +/* Skip frames for "finish". */ + +static struct frame_info * +skip_finish_frames (struct frame_info *frame) +{ + struct frame_info *start; + + do + { + start = frame; + + frame = skip_tailcall_frames (frame); + if (frame == NULL) + break; + + frame = skip_unwritable_frames (frame); + if (frame == NULL) + break; + } + while (start != frame); + + return frame; +} + /* "finish": Set a temporary breakpoint at the place the selected frame will return to, then continue. */ @@ -1973,7 +2000,7 @@ finish_command (char *arg, int from_tty) tp = inferior_thread (); - sm = new_finish_command_fsm (tp->num); + sm = new_finish_command_fsm (command_interp ()); tp->thread_fsm = &sm->thread_fsm; @@ -2007,11 +2034,6 @@ finish_command (char *arg, int from_tty) return; } - /* Ignore TAILCALL_FRAME type frames, they were executed already before - entering THISFRAME. */ - while (get_frame_type (frame) == TAILCALL_FRAME) - frame = get_prev_frame (frame); - /* Find the function we will return from. */ sm->function = find_pc_function (get_frame_pc (get_selected_frame (NULL))); @@ -2038,7 +2060,14 @@ finish_command (char *arg, int from_tty) if (execution_direction == EXEC_REVERSE) finish_backward (sm); else - finish_forward (sm, frame); + { + frame = skip_finish_frames (frame); + + if (frame == NULL) + error (_("Cannot find the caller frame.")); + + finish_forward (sm, frame); + } } @@ -2279,7 +2308,6 @@ default_print_one_register_info (struct ui_file *file, if (TYPE_CODE (regtype) == TYPE_CODE_FLT || TYPE_CODE (regtype) == TYPE_CODE_DECFLOAT) { - int j; 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)); @@ -2615,18 +2643,15 @@ proceed_after_attach (int pid) do_cleanups (old_chain); } -/* attach_command -- - 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. - and wait for the trace-trap that results from attaching. */ +/* See inferior.h. */ -static void -attach_command_post_wait (char *args, int from_tty, int async_exec) +void +setup_inferior (int from_tty) { struct inferior *inferior; inferior = current_inferior (); - inferior->control.stop_soon = NO_STOP_QUIETLY; + inferior->needs_setup = 0; /* If no exec file is yet known, try to determine it from the process itself. */ @@ -2642,8 +2667,37 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) target_post_attach (ptid_get_pid (inferior_ptid)); post_create_inferior (¤t_target, from_tty); +} + +/* What to do after the first program stops after attaching. */ +enum attach_post_wait_mode +{ + /* Do nothing. Leaves threads as they are. */ + ATTACH_POST_WAIT_NOTHING, + + /* Re-resume threads that are marked running. */ + ATTACH_POST_WAIT_RESUME, + + /* Stop all threads. */ + ATTACH_POST_WAIT_STOP, +}; - if (async_exec) +/* 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, */ + +static void +attach_post_wait (char *args, int from_tty, enum attach_post_wait_mode mode) +{ + struct inferior *inferior; + + inferior = current_inferior (); + inferior->control.stop_soon = NO_STOP_QUIETLY; + + if (inferior->needs_setup) + setup_inferior (from_tty); + + if (mode == ATTACH_POST_WAIT_RESUME) { /* The user requested an `attach&', so be sure to leave threads that didn't get a signal running. */ @@ -2663,13 +2717,11 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) } } } - else + else if (mode == ATTACH_POST_WAIT_STOP) { /* The user requested a plain `attach', so be sure to leave the inferior stopped. */ - async_enable_stdin (); - /* At least the current thread is already stopped. */ /* In all-stop, by definition, all threads have to be already @@ -2677,8 +2729,32 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) selected thread is stopped, others may still be executing. Be sure to explicitly stop all threads of the process. This should have no effect on already stopped threads. */ - if (target_is_non_stop_p ()) + if (non_stop) target_stop (pid_to_ptid (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 (); + + /* It's not defined which thread will report the attach + 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; + } + } + + switch_to_thread (lowest->ptid); + } /* Tell the user/frontend where we're stopped. */ normal_stop (); @@ -2691,35 +2767,43 @@ struct attach_command_continuation_args { char *args; int from_tty; - int async_exec; + enum attach_post_wait_mode mode; }; static void attach_command_continuation (void *args, int err) { - struct attach_command_continuation_args *a = args; + struct attach_command_continuation_args *a + = (struct attach_command_continuation_args *) args; if (err) return; - attach_command_post_wait (a->args, a->from_tty, a->async_exec); + 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 = 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. */ + void attach_command (char *args, int from_tty) { int async_exec; struct cleanup *args_chain; struct target_ops *attach_target; + struct inferior *inferior = current_inferior (); + enum attach_post_wait_mode mode; dont_repeat (); /* Not for the faint of heart */ @@ -2779,6 +2863,8 @@ attach_command (char *args, int from_tty) init_wait_for_inferior (); clear_proceed_status (0); + inferior->needs_setup = 1; + if (target_is_non_stop_p ()) { /* If we find that the current thread isn't stopped, explicitly @@ -2794,12 +2880,13 @@ attach_command (char *args, int from_tty) target_stop (pid_to_ptid (ptid_get_pid (inferior_ptid))); } + 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; - struct inferior *inferior = current_inferior (); /* Careful here. See comments in inferior.h. Basically some OSes don't ignore SIGSTOPs on continue requests anymore. We @@ -2808,11 +2895,11 @@ attach_command (char *args, int from_tty) STOP_QUIETLY_NO_SIGSTOP is for. */ inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP; - /* sync_execution mode. Wait for stop. */ + /* Wait for stop. */ a = XNEW (struct attach_command_continuation_args); a->args = xstrdup (args); a->from_tty = from_tty; - a->async_exec = async_exec; + a->mode = mode; add_inferior_continuation (attach_command_continuation, a, attach_command_continuation_free_args); /* Done with ARGS. */ @@ -2826,7 +2913,7 @@ attach_command (char *args, int from_tty) /* Done with ARGS. */ do_cleanups (args_chain); - attach_command_post_wait (args, from_tty, async_exec); + attach_post_wait (args, from_tty, mode); } /* We had just found out that the target was already attached to an @@ -2841,20 +2928,18 @@ void notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) { struct cleanup* old_chain; - int async_exec; + enum attach_post_wait_mode mode; old_chain = make_cleanup (null_cleanup, NULL); - /* If in non-stop, leave threads as running as they were. If - they're stopped for some reason other than us telling it to, the - target reports a signal != GDB_SIGNAL_0. We don't try to - resume threads with such a stop signal. */ - async_exec = non_stop; + mode = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING; if (!ptid_equal (inferior_ptid, null_ptid)) make_cleanup_restore_current_thread (); - switch_to_thread (ptid); + /* Avoid reading registers -- we haven't fetched the target + description yet. */ + switch_to_thread_no_regs (find_thread_ptid (ptid)); /* When we "notice" a new inferior we need to do all the things we would normally do if we had just attached to it. */ @@ -2875,7 +2960,7 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) a = XNEW (struct attach_command_continuation_args); a->args = xstrdup (""); a->from_tty = from_tty; - a->async_exec = async_exec; + a->mode = mode; add_inferior_continuation (attach_command_continuation, a, attach_command_continuation_free_args); @@ -2883,8 +2968,7 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) return; } - async_exec = leave_running; - attach_command_post_wait ("" /* args */, from_tty, async_exec); + attach_post_wait ("" /* args */, from_tty, mode); do_cleanups (old_chain); } @@ -2914,6 +2998,13 @@ detach_command (char *args, int from_tty) target_detach (args, from_tty); + /* The current inferior process was just detached successfully. Get + rid of breakpoints that no longer make sense. Note we don't do + this within target_detach because that is also used when + following child forks, and in that case we will want to transfer + breakpoints to the child, not delete them. */ + breakpoint_init_inferior (inf_exited); + /* If the solist is global across inferiors, don't clear it when we detach from a single inferior. */ if (!gdbarch_has_global_solist (target_gdbarch ())) @@ -2958,7 +3049,11 @@ interrupt_target_1 (int all_threads) ptid = minus_one_ptid; else ptid = inferior_ptid; - target_interrupt (ptid); + + if (non_stop) + target_stop (ptid); + else + target_interrupt (ptid); /* Tag the thread as having been explicitly requested to stop, so other parts of gdb know not to resume this thread automatically,