From 5c09a2c53c3d3259392ada37303af8033ab91c7e Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 14 Nov 2013 19:43:25 +0000 Subject: infrun.c:handle_inferior_event: Don't fall through in TARGET_WAITKIND_LOADED handling. Of all the TARGET_WAITKIND_XXXs event kinds other than TARGET_WAITKIND_STOPPED, TARGET_WAITKIND_LOADED is the only kind that doesn't end in a return, instead falling through to all the signal/breakpoint/stepping handling code. But it only falls through in the STOP_QUIETLY_NO_SIGSTOP and STOP_QUIETLY_REMOTE cases, which means the /* This is originated from start_remote(), start_inferior() and shared libraries hook functions. */ 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; } bit is eventually reached. All tests before that is reached will always fail. It's simpler to inline the stop_soon checks close to the TARGET_WAITKIND_LOADED code, which allows removing the fall through. Tested on x86_64 Fedora 17, but that doesn't exercise this TARGET_WAITKIND_LOADED. Also ran gdb.base/solib-disc.exp on Cygwin/gdbserver, which exercises reconnection while the inferior is stopped at an solib event, but then again, gdbserver always replies a regular trap on initial connection, instead of the last event the program had seen: Sending packet: $?#3f...Packet received: T0505:4ca72800;04:f8a62800;08:62fcc877;thread:d28; Sending packet: $Hc-1#09...Packet received: E01 Sending packet: $qAttached#8f...Packet received: 0 Packet qAttached (query-attached) is supported infrun: clear_proceed_status_thread (Thread 3368) Sending packet: $qOffsets#4b...Packet received: infrun: wait_for_inferior () infrun: target_wait (-1, status) = infrun: 42000 [Thread 3368], infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: infwait_normal_state infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x77c8fc62 infrun: quietly stopped infrun: stop_stepping So the only way to exercise this would be to hack gdbserver. I didn't go that far though. I'm reasonably confident this is correct. gdb/ 2013-11-14 Pedro Alves * infrun.c (handle_inferior_event) : Handle STOP_QUIETLY_NO_SIGSTOP and STOP_QUIETLY_REMOTE here. Assert we never fall through out of the TARGET_WAITKIND_LOADED case. --- gdb/ChangeLog | 7 +++++++ gdb/infrun.c | 24 ++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a9afe02..e85ceea 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2013-11-14 Pedro Alves + + * infrun.c (handle_inferior_event) : + Handle STOP_QUIETLY_NO_SIGSTOP and STOP_QUIETLY_REMOTE here. + Assert we never fall through out of the TARGET_WAITKIND_LOADED + case. + 2013-11-14 Tom Tromey * python/py-linetable.c (ltpy_has_line) diff --git a/gdb/infrun.c b/gdb/infrun.c index c9e2fe2..ba55686 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3319,6 +3319,8 @@ handle_inferior_event (struct execution_control_state *ecs) case TARGET_WAITKIND_LOADED: if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n"); + if (!ptid_equal (ecs->ptid, inferior_ptid)) + context_switch (ecs->ptid); /* Ignore gracefully during startup of the inferior, as it might be the shell which has just loaded some objects, otherwise add the symbols for the newly loaded objects. Also ignore at @@ -3330,8 +3332,6 @@ handle_inferior_event (struct execution_control_state *ecs) struct regcache *regcache; enum bpstat_signal_value sval; - if (!ptid_equal (ecs->ptid, inferior_ptid)) - context_switch (ecs->ptid); regcache = get_thread_regcache (ecs->ptid); handle_solib_event (); @@ -3370,13 +3370,9 @@ handle_inferior_event (struct execution_control_state *ecs) /* If we are skipping through a shell, or through shared library loading that we aren't interested in, resume the program. If - we're running the program normally, also resume. But stop if - we're attaching or setting up a remote connection. */ + we're running the program normally, also resume. */ if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY) { - if (!ptid_equal (ecs->ptid, inferior_ptid)) - context_switch (ecs->ptid); - /* Loading of shared libraries might have changed breakpoint addresses. Make sure new breakpoints are inserted. */ if (stop_soon == NO_STOP_QUIETLY @@ -3387,7 +3383,19 @@ handle_inferior_event (struct execution_control_state *ecs) return; } - break; + /* But stop if we're attaching or setting up a remote + connection. */ + if (stop_soon == STOP_QUIETLY_NO_SIGSTOP + || stop_soon == STOP_QUIETLY_REMOTE) + { + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n"); + stop_stepping (ecs); + return; + } + + internal_error (__FILE__, __LINE__, + _("unhandled stop_soon: %d"), (int) stop_soon); case TARGET_WAITKIND_SPURIOUS: if (debug_infrun) -- cgit v1.1