infrun.c: Split handle_inferior_event further.
authorPedro Alves <palves@redhat.com>
Thu, 14 Nov 2013 19:43:27 +0000 (19:43 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 14 Nov 2013 19:51:50 +0000 (19:51 +0000)
After the previous patches, we only ever reach the code after the
initial 'switch (ecs->ws.kind)' switch for TARGET_WAITKIND_STOPPED.
We can now factor out all that to its own function.

Unfortunately, stepped_after_stopped_by_watchpoint needed to move to
the ecs.  I think that indicates a state machine bug -- no event other
than TARGET_WAITKIND_STOPPED indicates a single-step actually
finished.  TARGET_WAITKIND_SYSCALL_XXX, TARGET_WAITKIND_FORK, etc. are
all events that are triggered from the kernel, _within_ a syscall,
IOW, from userspace's perspective, halfway through an instruction
being executed.  This might actually matter for the syscall events, as
syscalls can change memory (and thus trigger watchpoints).

gdb/
2013-11-14  Pedro Alves  <palves@redhat.com>

* infrun.c (struct execution_control_state)
<stepped_after_stopped_by_watchpoint>: New field.
(get_inferior_stop_soon): New function.
(handle_inferior_event): 'stepped_after_stopped_by_watchpoint' was
moved to struct execution_control_state -- adjust.  Use
get_inferior_stop_soon.  Split TARGET_WAITKIND_STOPPED handling to
new function.
(handle_signal_stop): New function, factored out from
handle_inferior_event.

gdb/ChangeLog
gdb/infrun.c

index 58e7f2e48d6353f20166aae22fc2628c645b65db..5b9428d3f27bd63f233c0a93303e33fcdc386827 100644 (file)
@@ -1,3 +1,15 @@
+2013-11-14  Pedro Alves  <palves@redhat.com>
+
+       * infrun.c (struct execution_control_state)
+       <stepped_after_stopped_by_watchpoint>: New field.
+       (get_inferior_stop_soon): New function.
+       (handle_inferior_event): 'stepped_after_stopped_by_watchpoint' was
+       moved to struct execution_control_state -- adjust.  Use
+       get_inferior_stop_soon.  Split TARGET_WAITKIND_STOPPED handling to
+       new function.
+       (handle_signal_stop): New function, factored out from
+       handle_inferior_event.
+
 2013-11-14  Pedro Alves  <palves@redhat.com>
 
        * break-catch-sig.c (signal_catchpoint_explains_signal): Adjust to
index 4d26e376841f4e6286d7c84f96f2f835238b72cf..52bb0643dcdb2eb8d3214cbbbe3f357605b50d19 100644 (file)
@@ -2424,6 +2424,11 @@ struct execution_control_state
   CORE_ADDR stop_func_end;
   const char *stop_func_name;
   int wait_some_more;
+
+  /* We were in infwait_step_watch_state or
+     infwait_nonstep_watch_state state, and the thread reported an
+     event.  */
+  int stepped_after_stopped_by_watchpoint;
 };
 
 static void handle_inferior_event (struct execution_control_state *ecs);
@@ -2432,6 +2437,7 @@ static void handle_step_into_function (struct gdbarch *gdbarch,
                                       struct execution_control_state *ecs);
 static void handle_step_into_function_backward (struct gdbarch *gdbarch,
                                                struct execution_control_state *ecs);
+static void handle_signal_stop (struct execution_control_state *ecs);
 static void check_exception_resume (struct execution_control_state *,
                                    struct frame_info *);
 
@@ -3132,6 +3138,18 @@ fill_in_stop_func (struct gdbarch *gdbarch,
     }
 }
 
+
+/* Return the STOP_SOON field of the inferior pointed at by PTID.  */
+
+static enum stop_kind
+get_inferior_stop_soon (ptid_t ptid)
+{
+  struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
+
+  gdb_assert (inf != NULL);
+  return inf->control.stop_soon;
+}
+
 /* Given an execution control state that has been freshly filled in by
    an event from the inferior, figure out what it means and take
    appropriate action.
@@ -3148,12 +3166,7 @@ fill_in_stop_func (struct gdbarch *gdbarch,
 static void
 handle_inferior_event (struct execution_control_state *ecs)
 {
-  struct frame_info *frame;
-  struct gdbarch *gdbarch;
-  int stopped_by_watchpoint;
-  int stepped_after_stopped_by_watchpoint = 0;
   enum stop_kind stop_soon;
-  int random_signal;
 
   if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
     {
@@ -3187,18 +3200,6 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
-  if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-      && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
-    {
-      struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
-
-      gdb_assert (inf);
-      stop_soon = inf->control.stop_soon;
-    }
-  else
-    stop_soon = NO_STOP_QUIETLY;
-
   /* Cache the last pid/waitstatus.  */
   target_last_wait_ptid = ecs->ptid;
   target_last_waitstatus = ecs->ws;
@@ -3295,7 +3296,7 @@ handle_inferior_event (struct execution_control_state *ecs)
         fprintf_unfiltered (gdb_stdlog,
                            "infrun: infwait_step_watch_state\n");
 
-      stepped_after_stopped_by_watchpoint = 1;
+      ecs->stepped_after_stopped_by_watchpoint = 1;
       break;
 
     case infwait_nonstep_watch_state:
@@ -3307,7 +3308,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* FIXME-maybe: is this cleaner than setting a flag?  Does it
          handle things like signals arriving and other things happening
          in combination correctly?  */
-      stepped_after_stopped_by_watchpoint = 1;
+      ecs->stepped_after_stopped_by_watchpoint = 1;
       break;
 
     default:
@@ -3330,6 +3331,8 @@ handle_inferior_event (struct execution_control_state *ecs)
          the beginning of an attach or remote session; we will query
          the full list of libraries once the connection is
          established.  */
+
+      stop_soon = get_inferior_stop_soon (ecs->ptid);
       if (stop_soon == NO_STOP_QUIETLY)
        {
          struct regcache *regcache;
@@ -3715,7 +3718,8 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
       ecs->event_thread->suspend.stop_signal = ecs->ws.value.sig;
-      break;
+      handle_signal_stop (ecs);
+      return;
 
     case TARGET_WAITKIND_NO_HISTORY:
       if (debug_infrun)
@@ -3735,6 +3739,18 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       stop_stepping (ecs);
       return;
     }
+}
+
+/* Come here when the program has stopped with a signal.  */
+
+static void
+handle_signal_stop (struct execution_control_state *ecs)
+{
+  struct frame_info *frame;
+  struct gdbarch *gdbarch;
+  int stopped_by_watchpoint;
+  enum stop_kind stop_soon;
+  int random_signal;
 
   if (ecs->ws.kind == TARGET_WAITKIND_STOPPED)
     {
@@ -4022,7 +4038,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       singlestep_breakpoints_inserted_p = 0;
     }
 
-  if (stepped_after_stopped_by_watchpoint)
+  if (ecs->stepped_after_stopped_by_watchpoint)
     stopped_by_watchpoint = 0;
   else
     stopped_by_watchpoint = watchpoints_triggered (&ecs->ws);
@@ -4167,6 +4183,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
 
   /* 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)