--- ../orig/gdb/breakpoint.c +++ ./gdb/breakpoint.c --- ../orig/gdb/infcmd.c +++ ./gdb/infcmd.c @@ -2741,7 +2741,7 @@ struct thread_info *lowest = inferior_thread (); int pid = current_inferior ()->pid; - stop_all_threads (); + stop_all_threads (inferior); /* It's not defined which thread will report the attach stop. For consistency, always select the thread with @@ -2920,6 +2920,28 @@ attach_post_wait (args, from_tty, mode); } +/* Helper function for any_global_breakpoint. If B is a global + break or catch point, return 1 (which will make + 'breakpoint_find_if' return). Otherwise, return 0. */ + +static int +any_global_breakpoint_1 (struct breakpoint *b, + void *data) +{ + if (b->enable_state == bp_enabled && b->thread == -1) + return 1; + else + return 0; +} + +static int +any_global_breakpoint (void) +{ + struct breakpoint *b = breakpoint_find_if (any_global_breakpoint_1, NULL); + + return b != NULL; +} + /* We had just found out that the target was already attached to an inferior. PTID points at a thread of this new inferior, that is the most likely to be stopped right now, but not necessarily so. @@ -2948,7 +2970,9 @@ /* 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 (!leave_running && + any_global_breakpoint () && + is_executing (inferior_ptid)) { struct attach_command_continuation_args *a; struct inferior *inferior = current_inferior (); --- ../orig/gdb/inferior.c +++ ./gdb/inferior.c @@ -320,13 +320,27 @@ void discard_all_inferiors (void) { - struct inferior *inf; + struct inferior *inf, *infnext; - for (inf = inferior_list; inf; inf = inf->next) + for (inf = inferior_list; inf; inf = infnext) { - if (inf->pid != 0) - exit_inferior_silent (inf->pid); + infnext = inf->next; + + if (inf->num == 1) + { + if (inf->pid != 0) + exit_inferior_1 (inf, 1); + } + else + delete_inferior (inf); } + + inferior_ptid = null_ptid; + inferior_list->pid = 0; + set_current_inferior (inferior_list); + switch_to_thread (null_ptid); + + highest_inferior_num = inferior_list->num; } struct inferior * --- ../orig/gdb/infrun.c +++ ./gdb/infrun.c @@ -2584,7 +2584,7 @@ /* Fallback to stepping over the breakpoint in-line. */ if (target_is_non_stop_p ()) - stop_all_threads (); + stop_all_threads (tp->inf); set_step_over_info (get_regcache_aspace (regcache), regcache_read_pc (regcache), 0, tp->global_num); @@ -4496,7 +4496,7 @@ /* See infrun.h. */ void -stop_all_threads (void) +stop_all_threads (struct inferior *inferior) { /* We may need multiple passes to discover all threads. */ int pass; @@ -4509,6 +4509,11 @@ if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: stop_all_threads\n"); + /* With global break points we have always to + stop all threads of all inferiors. */ + if (gdbarch_has_global_breakpoints (target_gdbarch ())) + inferior = NULL; + entry_ptid = inferior_ptid; old_chain = make_cleanup (switch_to_thread_cleanup, &entry_ptid); @@ -4539,6 +4544,8 @@ to tell the target to stop. */ ALL_NON_EXITED_THREADS (t) { + if (inferior != NULL && inferior != t->inf) + continue; if (t->executing) { /* If already stopping, don't request a stop again. @@ -5442,7 +5449,7 @@ ALL_NON_EXITED_THREADS (tp) { - if (tp == event_thread) + if (tp == event_thread || tp->inf != event_thread->inf) { if (debug_infrun) fprintf_unfiltered (gdb_stdlog, @@ -7705,7 +7712,7 @@ /* If all-stop, but the target is always in non-stop mode, stop all threads now that we're presenting the stop to the user. */ if (!non_stop && target_is_non_stop_p ()) - stop_all_threads (); + stop_all_threads (NULL); } /* Like keep_going, but passes the signal to the inferior, even if the @@ -7821,7 +7828,7 @@ we're about to step over, otherwise other threads could miss it. */ if (step_over_info_valid_p () && target_is_non_stop_p ()) - stop_all_threads (); + stop_all_threads (ecs->event_thread->inf); /* Stop stepping if inserting breakpoints fails. */ TRY --- ../orig/gdb/infrun.h +++ ./gdb/infrun.h @@ -110,8 +110,12 @@ extern void set_last_target_status (ptid_t ptid, struct target_waitstatus status); -/* Stop all threads. Only returns after everything is halted. */ -extern void stop_all_threads (void); +/* Stop all threads belonging to inf. + When called with inf == NULL, stop all threads of all inferiors. + With gdbarch_has_global_breakpoints () is true, always stop all + threads of all inferiors. + Only returns after everything is halted. */ +extern void stop_all_threads (struct inferior *inf); extern void prepare_for_detach (void); --- ../orig/gdb/remote.c +++ ./gdb/remote.c @@ -1789,8 +1789,24 @@ /* In the traditional debugging scenario, there's a 1-1 match between program/address spaces. We simply bind the inferior to the program space's address space. */ - inf = current_inferior (); - inferior_appeared (inf, pid); + + inf = find_inferior_id (pid); + if (inf == NULL) + { + if (current_inferior () ->pid == 0) + { + inf = current_inferior (); + inferior_appeared (inf, pid); + } + else + { + inf = add_inferior (pid); + inf->aspace = current_inferior () ->aspace; + inf->pspace = current_program_space; + inf->gdbarch = current_inferior () ->gdbarch; + copy_inferior_target_desc_info(inf, current_inferior ()); + } + } } inf->attach_flag = attached; @@ -1801,6 +1817,10 @@ if (try_open_exec && get_exec_file (0) == NULL) exec_file_locate_attach (pid, 0, 1); + set_current_inferior (inf); + + inferior_ptid = pid_to_ptid (pid); + return inf; } @@ -1902,6 +1922,9 @@ /* This is really a new thread. Add it. */ remote_add_thread (currthread, running, executing); + if (ptid_is_pid (inferior_ptid) + && pid == ptid_get_pid (inferior_ptid)) + inferior_ptid = currthread; /* If we found a new inferior, let the common code do whatever it needs to with it (e.g., read shared libraries, insert @@ -3937,7 +3960,7 @@ the inferiors. */ if (!non_stop) { - stop_all_threads (); + stop_all_threads (NULL); /* If all threads of an inferior were already stopped, we haven't setup the inferior yet. */