Slightly tweak and clarify target_resume's interface
authorPedro Alves <pedro@palves.net>
Thu, 21 Apr 2022 13:20:36 +0000 (14:20 +0100)
committerPedro Alves <pedro@palves.net>
Fri, 29 Apr 2022 11:33:27 +0000 (12:33 +0100)
The current target_resume interface is a bit odd & non-intuitive.
I've found myself explaining it a couple times the recent past, while
reviewing patches that assumed STEP/SIGNAL always applied to the
passed in PTID.  It goes like this today:

  - if the passed in PTID is a thread, then the step/signal request is
    for that thread.

  - otherwise, if PTID is a wildcard (all threads or all threads of
    process), the step/signal request is for inferior_ptid, and PTID
    indicates which set of threads run free.

Because GDB always switches the current thread to "leader" thread
being resumed/stepped/signalled, we can simplify this a bit to:

  - step/signal are always for inferior_ptid.

  - PTID indicates the set of threads that run free.

Still not ideal, but it's a minimal change and at least there are no
special cases this way.

That's what this patch does.  It renames the PTID parameter to
SCOPE_PTID, adds some assertions to target_resume, and tweaks
target_resume's description.  In addition, it also renames PTID to
SCOPE_PTID in the remote and linux-nat targets, and simplifies their
implementation a little bit.  Other targets could do the same, but
they don't have to.

Change-Id: I02a2ec2ab3a3e9b191de1e9a84f55c17cab7daaf

gdb/linux-nat.c
gdb/remote.c
gdb/target.c
gdb/target.h

index dff8d07d3f7279c462dbb5d9fe700e05ad01a4c6..740cc0ddfc02f91b5bdfd9dc71042a4887574eb4 100644 (file)
@@ -1595,32 +1595,22 @@ resume_set_callback (struct lwp_info *lp)
 }
 
 void
-linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
+linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
 {
   struct lwp_info *lp;
-  int resume_many;
 
   linux_nat_debug_printf ("Preparing to %s %s, %s, inferior_ptid %s",
                          step ? "step" : "resume",
-                         ptid.to_string ().c_str (),
+                         scope_ptid.to_string ().c_str (),
                          (signo != GDB_SIGNAL_0
                           ? strsignal (gdb_signal_to_host (signo)) : "0"),
                          inferior_ptid.to_string ().c_str ());
 
-  /* A specific PTID means `step only this process id'.  */
-  resume_many = (minus_one_ptid == ptid
-                || ptid.is_pid ());
-
   /* Mark the lwps we're resuming as resumed and update their
      last_resume_kind to resume_continue.  */
-  iterate_over_lwps (ptid, resume_set_callback);
+  iterate_over_lwps (scope_ptid, resume_set_callback);
 
-  /* See if it's the current inferior that should be handled
-     specially.  */
-  if (resume_many)
-    lp = find_lwp_pid (inferior_ptid);
-  else
-    lp = find_lwp_pid (ptid);
+  lp = find_lwp_pid (inferior_ptid);
   gdb_assert (lp != NULL);
 
   /* Remember if we're stepping.  */
@@ -1669,11 +1659,12 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
       return;
     }
 
-  if (resume_many)
-    iterate_over_lwps (ptid, [=] (struct lwp_info *info)
-                            {
-                              return linux_nat_resume_callback (info, lp);
-                            });
+  /* No use iterating unless we're resuming other threads.  */
+  if (scope_ptid != lp->ptid)
+    iterate_over_lwps (scope_ptid, [=] (struct lwp_info *info)
+      {
+       return linux_nat_resume_callback (info, lp);
+      });
 
   linux_nat_debug_printf ("%s %s, %s (resume event thread)",
                          step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
index 562cc586f2bfe2d764a64fb228a1260888461ae6..ff98024cd781ea27de8582a84ba2965f43d23a16 100644 (file)
@@ -737,7 +737,7 @@ public: /* Remote specific methods.  */
 
   char *append_resumption (char *p, char *endp,
                           ptid_t ptid, int step, gdb_signal siggnal);
-  int remote_resume_with_vcont (ptid_t ptid, int step,
+  int remote_resume_with_vcont (ptid_t scope_ptid, int step,
                                gdb_signal siggnal);
 
   thread_info *add_current_inferior_and_thread (const char *wait_status);
@@ -6274,9 +6274,8 @@ remote_target::remote_vcont_probe ()
    thread to be resumed is PTID; STEP and SIGGNAL indicate whether the
    resumed thread should be single-stepped and/or signalled.  If PTID
    equals minus_one_ptid, then all threads are resumed; if PTID
-   represents a process, then all threads of the process are resumed;
-   the thread to be stepped and/or signalled is given in the global
-   INFERIOR_PTID.  */
+   represents a process, then all threads of the process are
+   resumed.  */
 
 char *
 remote_target::append_resumption (char *p, char *endp,
@@ -6433,18 +6432,15 @@ remote_target::remote_resume_with_hc (ptid_t ptid, int step,
   putpkt (buf);
 }
 
-/* Resume the remote inferior by using a "vCont" packet.  The thread
-   to be resumed is PTID; STEP and SIGGNAL indicate whether the
-   resumed thread should be single-stepped and/or signalled.  If PTID
-   equals minus_one_ptid, then all threads are resumed; the thread to
-   be stepped and/or signalled is given in the global INFERIOR_PTID.
-   This function returns non-zero iff it resumes the inferior.
+/* Resume the remote inferior by using a "vCont" packet.  SCOPE_PTID,
+   STEP, and SIGGNAL have the same meaning as in target_resume.  This
+   function returns non-zero iff it resumes the inferior.
 
    This function issues a strict subset of all possible vCont commands
    at the moment.  */
 
 int
-remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
+remote_target::remote_resume_with_vcont (ptid_t scope_ptid, int step,
                                         enum gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
@@ -6470,7 +6466,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
 
   p += xsnprintf (p, endp - p, "vCont");
 
-  if (ptid == magic_null_ptid)
+  if (scope_ptid == magic_null_ptid)
     {
       /* MAGIC_NULL_PTID means that we don't have any active threads,
         so we don't have any TID numbers the inferior will
@@ -6478,7 +6474,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
         a TID.  */
       append_resumption (p, endp, minus_one_ptid, step, siggnal);
     }
-  else if (ptid == minus_one_ptid || ptid.is_pid ())
+  else if (scope_ptid == minus_one_ptid || scope_ptid.is_pid ())
     {
       /* Resume all threads (of all processes, or of a single
         process), with preference for INFERIOR_PTID.  This assumes
@@ -6492,15 +6488,15 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
 
       /* Also pass down any pending signaled resumption for other
         threads not the current.  */
-      p = append_pending_thread_resumptions (p, endp, ptid);
+      p = append_pending_thread_resumptions (p, endp, scope_ptid);
 
       /* And continue others without a signal.  */
-      append_resumption (p, endp, ptid, /*step=*/ 0, GDB_SIGNAL_0);
+      append_resumption (p, endp, scope_ptid, /*step=*/ 0, GDB_SIGNAL_0);
     }
   else
     {
-      /* Scheduler locking; resume only PTID.  */
-      append_resumption (p, endp, ptid, step, siggnal);
+      /* Scheduler locking; resume only SCOPE_PTID.  */
+      append_resumption (p, endp, scope_ptid, step, siggnal);
     }
 
   gdb_assert (strlen (rs->buf.data ()) < get_remote_packet_size ());
@@ -6523,7 +6519,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
 /* Tell the remote machine to resume.  */
 
 void
-remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
+remote_target::resume (ptid_t scope_ptid, int step, enum gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -6536,18 +6532,20 @@ remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
      able to do vCont action coalescing.  */
   if (target_is_non_stop_p () && ::execution_direction != EXEC_REVERSE)
     {
-      remote_thread_info *remote_thr;
-
-      if (minus_one_ptid == ptid || ptid.is_pid ())
-       remote_thr = get_remote_thread_info (this, inferior_ptid);
-      else
-       remote_thr = get_remote_thread_info (this, ptid);
+      remote_thread_info *remote_thr
+       = get_remote_thread_info (inferior_thread ());
 
       /* We don't expect the core to ask to resume an already resumed (from
          its point of view) thread.  */
       gdb_assert (remote_thr->get_resume_state () == resume_state::NOT_RESUMED);
 
       remote_thr->set_resumed_pending_vcont (step, siggnal);
+
+      /* There's actually nothing that says that the core can't
+        request a wildcard resume in non-stop mode, though.  It's
+        just that we know it doesn't currently, so we don't bother
+        with it.  */
+      gdb_assert (scope_ptid == inferior_ptid);
       return;
     }
 
@@ -6563,11 +6561,11 @@ remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
   rs->last_resume_exec_dir = ::execution_direction;
 
   /* Prefer vCont, and fallback to s/c/S/C, which use Hc.  */
-  if (!remote_resume_with_vcont (ptid, step, siggnal))
-    remote_resume_with_hc (ptid, step, siggnal);
+  if (!remote_resume_with_vcont (scope_ptid, step, siggnal))
+    remote_resume_with_hc (scope_ptid, step, siggnal);
 
   /* Update resumed state tracked by the remote target.  */
-  for (thread_info *tp : all_non_exited_threads (this, ptid))
+  for (thread_info *tp : all_non_exited_threads (this, scope_ptid))
     get_remote_thread_info (tp)->set_resumed ();
 
   /* We've just told the target to resume.  The remote server will
index 7d291fd4d0d24cadff3e68acd3211aad21395eda..1063f8086bc97527ebf298a7cf892dcd1a133f4b 100644 (file)
@@ -2655,21 +2655,24 @@ target_thread_info_to_thread_handle (struct thread_info *tip)
 }
 
 void
-target_resume (ptid_t ptid, int step, enum gdb_signal signal)
+target_resume (ptid_t scope_ptid, int step, enum gdb_signal signal)
 {
   process_stratum_target *curr_target = current_inferior ()->process_target ();
   gdb_assert (!curr_target->commit_resumed_state);
 
+  gdb_assert (inferior_ptid != null_ptid);
+  gdb_assert (inferior_ptid.matches (scope_ptid));
+
   target_dcache_invalidate ();
 
-  current_inferior ()->top_target ()->resume (ptid, step, signal);
+  current_inferior ()->top_target ()->resume (scope_ptid, step, signal);
 
-  registers_changed_ptid (curr_target, ptid);
+  registers_changed_ptid (curr_target, scope_ptid);
   /* We only set the internal executing state here.  The user/frontend
      running state is set at a higher level.  This also clears the
      thread's stop_pc as side effect.  */
-  set_executing (curr_target, ptid, true);
-  clear_inline_frame_state (curr_target, ptid);
+  set_executing (curr_target, scope_ptid, true);
+  clear_inline_frame_state (curr_target, scope_ptid);
 
   if (target_can_async_p ())
     target_async (1);
index 093178af0bcae58987942f65026a0eb978697ea2..f77dbf051130dce85b97d03a94d49268f9da10eb 100644 (file)
@@ -1471,23 +1471,32 @@ extern void target_detach (inferior *inf, int from_tty);
 
 extern void target_disconnect (const char *, int);
 
-/* Resume execution (or prepare for execution) of a target thread,
-   process or all processes.  STEP says whether to hardware
-   single-step or to run free; SIGGNAL is the signal to be given to
-   the target, or GDB_SIGNAL_0 for no signal.  The caller may not pass
-   GDB_SIGNAL_DEFAULT.  A specific PTID means `step/resume only this
-   process id'.  A wildcard PTID (all threads, or all threads of
-   process) means `step/resume INFERIOR_PTID, and let other threads
-   (for which the wildcard PTID matches) resume with their
-   'thread->suspend.stop_signal' signal (usually GDB_SIGNAL_0) if it
-   is in "pass" state, or with no signal if in "no pass" state.
+/* Resume execution (or prepare for execution) of the current thread
+   (INFERIOR_PTID), while optionally letting other threads of the
+   current process or all processes run free.
+
+   STEP says whether to hardware single-step the current thread or to
+   let it run free; SIGNAL is the signal to be given to the current
+   thread, or GDB_SIGNAL_0 for no signal.  The caller may not pass
+   GDB_SIGNAL_DEFAULT.
+
+   SCOPE_PTID indicates the resumption scope.  I.e., which threads
+   (other than the current) run free.  If resuming a single thread,
+   SCOPE_PTID is the same thread as the current thread.  A wildcard
+   SCOPE_PTID (all threads, or all threads of process) lets threads
+   other than the current (for which the wildcard SCOPE_PTID matches)
+   resume with their 'thread->suspend.stop_signal' signal (usually
+   GDB_SIGNAL_0) if it is in "pass" state, or with no signal if in "no
+   pass" state.  Note neither STEP nor SIGNAL apply to any thread
+   other than the current.
 
    In order to efficiently handle batches of resumption requests,
    targets may implement this method such that it records the
    resumption request, but defers the actual resumption to the
    target_commit_resume method implementation.  See
    target_commit_resume below.  */
-extern void target_resume (ptid_t ptid, int step, enum gdb_signal signal);
+extern void target_resume (ptid_t scope_ptid,
+                          int step, enum gdb_signal signal);
 
 /* Ensure that all resumed threads are committed to the target.