This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/7] 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-10-31  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.
---
 gdb/infrun.c | 24 ++++++++++++++++--------
 1 file 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)
-- 
1.7.11.7


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]