diff options
author | Pedro Alves <palves@redhat.com> | 2013-11-14 19:43:25 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2013-11-14 19:43:25 +0000 |
commit | 5c09a2c53c3d3259392ada37303af8033ab91c7e (patch) | |
tree | 10ebfbed836e7b7e2c617249b7dd272c88d763e3 /gdb/infrun.c | |
parent | 94e49e160d0c3f0b1b838f9963b1da5d3cfc795b (diff) | |
download | gdb-5c09a2c53c3d3259392ada37303af8033ab91c7e.zip gdb-5c09a2c53c3d3259392ada37303af8033ab91c7e.tar.gz gdb-5c09a2c53c3d3259392ada37303af8033ab91c7e.tar.bz2 |
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 <palves@redhat.com>
* infrun.c (handle_inferior_event) <TARGET_WAITKIND_LOADED>:
Handle STOP_QUIETLY_NO_SIGSTOP and STOP_QUIETLY_REMOTE here.
Assert we never fall through out of the TARGET_WAITKIND_LOADED
case.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 24 |
1 files changed, 16 insertions, 8 deletions
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) |