From 36fa80421a9edbf97fc6081557509937bc717bc1 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 14 Nov 2013 19:43:27 +0000 Subject: [PATCH] infrun.c:handle_signal_stop: Move initial connection/attachment handling code earlier. Before all this stop_soon handling, we have code that can end in keep_going. Particularly, the thread_hop_needed code looked suspicious considering breakpoint always-inserted mode, though on closer inspection, it'd take connecting to multiple remote targets that shared the same address space to trigger that. Still, I think it's clearer if all this remote connection setup / attach code is placed early, before any keep_going path could be reached. gdb/ 2013-11-14 Pedro Alves * infrun.c (handle_signal_stop): Move STOP_QUIETLY, STOP_QUIETLY_REMOTE and 'stop_after_trap' handling earlier. --- gdb/ChangeLog | 5 +++ gdb/infrun.c | 108 ++++++++++++++++++++++++++------------------------ 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5b9428d3f27..de158799654 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2013-11-14 Pedro Alves + + * infrun.c (handle_signal_stop): Move STOP_QUIETLY, + STOP_QUIETLY_REMOTE and 'stop_after_trap' handling earlier. + 2013-11-14 Pedro Alves * infrun.c (struct execution_control_state) diff --git a/gdb/infrun.c b/gdb/infrun.c index 52bb0643dcd..0b8dffe08a9 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3799,6 +3799,63 @@ handle_signal_stop (struct execution_control_state *ecs) do_cleanups (old_chain); } + /* This is originated from start_remote(), start_inferior() and + shared libraries hook functions. */ + stop_soon = get_inferior_stop_soon (ecs->ptid); + if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE) + { + if (!ptid_equal (ecs->ptid, inferior_ptid)) + context_switch (ecs->ptid); + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n"); + stop_print_frame = 1; + stop_stepping (ecs); + return; + } + + if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP + && stop_after_trap) + { + if (!ptid_equal (ecs->ptid, inferior_ptid)) + context_switch (ecs->ptid); + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n"); + stop_print_frame = 0; + stop_stepping (ecs); + return; + } + + /* This originates from attach_command(). We need to overwrite + the stop_signal here, because some kernels don't ignore a + SIGSTOP in a subsequent ptrace(PTRACE_CONT,SIGSTOP) call. + See more comments in inferior.h. On the other hand, if we + get a non-SIGSTOP, report it to the user - assume the backend + will handle the SIGSTOP if it should show up later. + + Also consider that the attach is complete when we see a + SIGTRAP. Some systems (e.g. Windows), and stubs supporting + target extended-remote report it instead of a SIGSTOP + (e.g. gdbserver). We already rely on SIGTRAP being our + signal, so this is no exception. + + Also consider that the attach is complete when we see a + GDB_SIGNAL_0. In non-stop mode, GDB will explicitly tell + the target to stop all threads of the inferior, in case the + low level attach operation doesn't stop them implicitly. If + they weren't stopped implicitly, then the stub will report a + GDB_SIGNAL_0, meaning: stopped for no particular reason + other than GDB's request. */ + if (stop_soon == STOP_QUIETLY_NO_SIGSTOP + && (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP + || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP + || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0)) + { + stop_print_frame = 1; + stop_stepping (ecs); + ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0; + return; + } + if (stepping_past_singlestep_breakpoint) { gdb_assert (singlestep_breakpoints_inserted_p); @@ -4171,57 +4228,6 @@ handle_signal_stop (struct execution_control_state *ecs) } } - if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP - && stop_after_trap) - { - if (debug_infrun) - fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n"); - stop_print_frame = 0; - stop_stepping (ecs); - return; - } - - /* This is originated from start_remote(), start_inferior() and - shared libraries hook functions. */ - stop_soon = get_inferior_stop_soon (ecs->ptid); - if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE) - { - if (debug_infrun) - fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n"); - stop_stepping (ecs); - return; - } - - /* This originates from attach_command(). We need to overwrite - the stop_signal here, because some kernels don't ignore a - SIGSTOP in a subsequent ptrace(PTRACE_CONT,SIGSTOP) call. - See more comments in inferior.h. On the other hand, if we - get a non-SIGSTOP, report it to the user - assume the backend - will handle the SIGSTOP if it should show up later. - - Also consider that the attach is complete when we see a - SIGTRAP. Some systems (e.g. Windows), and stubs supporting - target extended-remote report it instead of a SIGSTOP - (e.g. gdbserver). We already rely on SIGTRAP being our - signal, so this is no exception. - - Also consider that the attach is complete when we see a - GDB_SIGNAL_0. In non-stop mode, GDB will explicitly tell - the target to stop all threads of the inferior, in case the - low level attach operation doesn't stop them implicitly. If - they weren't stopped implicitly, then the stub will report a - GDB_SIGNAL_0, meaning: stopped for no particular reason - other than GDB's request. */ - if (stop_soon == STOP_QUIETLY_NO_SIGSTOP - && (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP - || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP - || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0)) - { - stop_stepping (ecs); - ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0; - return; - } - /* See if there is a breakpoint/watchpoint/catchpoint/etc. that handles this event. */ ecs->event_thread->control.stop_bpstat -- 2.39.5