public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: Tom Tromey <tom@tromey.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH v2 23/24] Require always-non-stop for multi-target resumptions
Date: Mon, 30 Dec 2019 18:30:00 -0000	[thread overview]
Message-ID: <20fe7d0b-d6c3-5eb4-9b44-b9cd86f0e576@redhat.com> (raw)
In-Reply-To: <877e4j4plh.fsf@tromey.com>

Hello,

On 11/1/19 2:51 PM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
> 
> Pedro> Currently, we can only support resuming multiple targets at the same
> Pedro> time if all targets are in non-stop mode (or user-visible all-stop
> Pedro> mode with target backend in non-stop mode).
> 
> I don't understand this, but I would like to.
> 
> I would have thought that target-async would be enough here.  As in, the
> necessary part is that target events be integrated with the event loop,
> so that multiple event sources can be selected on at once.
> 
> Why is non-stop needed instead?

The main reason is the remote target -- in all-stop mode, the remote protocol
is synchronous, irrespective of target-async.  I.e., as soon as
you resume the remote target in all-stop (with e.g., vCont), you can't send any
packet to the remote until it reports a stop.  The non-stop variant of the protocol
makes vCont be asynchronous instead.  A vCont results in an immediate "OK" reply,
and then stops are reported via an asynchronous mechanism (%Stop).  So if the
remote backend is in non-stop mode, we can talk to it even if some thread
is running.  This makes things simpler for the common code.  For example, breakpoint
re-set resets every breakpoint and location, and that results in reading memory
from all targets.  If a remote all-stop target is running, then that memory read
will fail, because we can't talk to the remote all-stop target until it fully
stops.  See <https://sourceware.org/ml/gdb-patches/2019-10/msg01052.html>.
Another place that needs more work is where we call stop_all_threads, which
needs to be taught to only explicitly pause all threads of a target one
by one if the target is in non-stop mode.  I ran into things like these
when I last tried to make it work, which made me punt until the
main chunks of multi-target are in.

How about this alternative comment?

+/* Check that all the targets we're about to resume are in non-stop
+   mode.  Ideally, we'd only care whether all targets support
+   target-async, but we're not there yet.  E.g., stop_all_threads
+   doesn't know how to handle all-stop targets.  Also, the remote
+   protocol in all-stop mode is synchronous, irrespective of
+   target-async, which means that things like a breakpoint re-set
+   triggered by one target would try to read memory from all targets
+   and fail.  */
+
+static void
+check_multi_target_resumption (process_stratum_target *resume_target)


From a33b584acec4af5d11dc35ec78afed0bf25742ff Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Wed, 30 Oct 2019 16:51:04 +0000
Subject: [PATCH] Require always-non-stop for multi-target resumptions

Currently, we can only support resuming multiple targets at the same
time if all targets are in non-stop mode (or user-visible all-stop
mode with target backend in non-stop mode).

This patch makes GDB error out if the user tries to resume more than
one target at the same time and one of the resumed targets isn't in
non-stop mode:

 (gdb) info inferiors
   Num  Description       Connection                Executable
   1    process 15303     1 (native)                a.out
 * 2    process 15286     2 (extended-remote :9999) a.out
 (gdb) set schedule-multiple on
 (gdb) c
 Continuing.
 Connection 2 (extended-remote :9999) does not support multi-target resumption.

This is here later in the series instead of in the main multi-target
patch because it depends the previous patch, which added
process_stratum_target::connection_string().

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* infrun.c: Include "target-connection.h".
	(check_multi_target_resumption): New.
	(proceed): Call it.
	* target-connection.c (make_target_connection_string): Make
	static.
	* target-connection.h (make_target_connection_string): Declare.
---
 gdb/infrun.c            | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/target-connection.c |  7 ++----
 gdb/target-connection.h |  8 +++++++
 3 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 688f9e029a..ce2de256df 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -28,6 +28,7 @@
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "target.h"
+#include "target-connection.h"
 #include "gdbthread.h"
 #include "annotate.h"
 #include "symfile.h"
@@ -2881,6 +2882,61 @@ commit_resume_all_targets ()
     }
 }
 
+/* Check that all the targets we're about to resume are in non-stop
+   mode.  Ideally, we'd only care whether all targets support
+   target-async, but we're not there yet.  E.g., stop_all_threads
+   doesn't know how to handle all-stop targets.  Also, the remote
+   protocol in all-stop mode is synchronous, irrespective of
+   target-async, which means that things like a breakpoint re-set
+   triggered by one target would try to read memory from all targets
+   and fail.  */
+
+static void
+check_multi_target_resumption (process_stratum_target *resume_target)
+{
+  if (!non_stop && resume_target == nullptr)
+    {
+      scoped_restore_current_thread restore_thread;
+
+      /* This is used to track whether we're resuming more than one
+	 target.  */
+      process_stratum_target *first_connection = nullptr;
+
+      /* The first inferior we see with a target that does not work in
+	 always-non-stop mode.  */
+      inferior *first_not_non_stop = nullptr;
+
+      for (inferior *inf : all_non_exited_inferiors (resume_target))
+	{
+	  switch_to_inferior_no_thread (inf);
+
+	  if (!target_has_execution)
+	    continue;
+
+	  process_stratum_target *proc_target
+	    = current_inferior ()->process_target();
+
+	  if (!target_is_non_stop_p ())
+	    first_not_non_stop = inf;
+
+	  if (first_connection == nullptr)
+	    first_connection = proc_target;
+	  else if (first_connection != proc_target
+		   && first_not_non_stop != nullptr)
+	    {
+	      switch_to_inferior_no_thread (first_not_non_stop);
+
+	      proc_target = current_inferior ()->process_target();
+
+	      error (_("Connection %d (%s) does not support "
+		       "multi-target resumption."),
+		     proc_target->connection_number,
+		     make_target_connection_string (proc_target).c_str ());
+	    }
+	}
+    }
+}
+
 /* Basic routine for continuing the program in various fashions.
 
    ADDR is the address to resume at, or -1 for resume where stopped.
@@ -2931,6 +2987,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   process_stratum_target *resume_target
     = user_visible_resume_target (resume_ptid);
 
+  check_multi_target_resumption (resume_target);
+
   if (addr == (CORE_ADDR) -1)
     {
       if (pc == cur_thr->suspend.stop_pc
diff --git a/gdb/target-connection.c b/gdb/target-connection.c
index a079f218bd..dd0300a82b 100644
--- a/gdb/target-connection.c
+++ b/gdb/target-connection.c
@@ -53,12 +53,9 @@ connection_list_remove (process_stratum_target *t)
   t->connection_number = 0;
 }
 
-/* Make a target connection string for T.  This is usually T's
-   shortname, but it includes the result of
-   process_stratum_target::connection_string() too if T supports
-   it.  */
+/* See target-connection.h.  */
 
-static std::string
+std::string
 make_target_connection_string (process_stratum_target *t)
 {
   if (t->connection_string () != NULL)
diff --git a/gdb/target-connection.h b/gdb/target-connection.h
index 0e2dc128d8..0b31924b99 100644
--- a/gdb/target-connection.h
+++ b/gdb/target-connection.h
@@ -20,6 +20,8 @@
 #ifndef TARGET_CONNECTION_H
 #define TARGET_CONNECTION_H
 
+#include <string>
+
 struct process_stratum_target;
 
 /* Add a process target to the connection list, if not already
@@ -29,4 +31,10 @@ void connection_list_add (process_stratum_target *t);
 /* Remove a process target from the connection list.  */
 void connection_list_remove (process_stratum_target *t);
 
+/* Make a target connection string for T.  This is usually T's
+   shortname, but it includes the result of
+   process_stratum_target::connection_string() too if T supports
+   it.  */
+std::string make_target_connection_string (process_stratum_target *t);
+
 #endif /* TARGET_CONNECTION_H */

-- 
2.14.5

  reply	other threads:[~2019-12-30 18:30 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-17 22:50 [PATCH v2 00/24] Multi-target support Pedro Alves
2019-10-17 22:50 ` [PATCH v2 16/24] Fix reconnecting to a gdbserver already debugging multiple processes, I Pedro Alves
2019-10-17 22:50 ` [PATCH v2 02/24] Don't rely on inferior_ptid in record_full_wait Pedro Alves
2019-11-01 14:54   ` Tom Tromey
2019-12-20 17:49     ` Pedro Alves
2019-12-20 18:57       ` Tom Tromey
2019-10-17 22:50 ` [PATCH v2 17/24] Fix reconnecting to a gdbserver already debugging multiple processes, II Pedro Alves
2019-10-17 22:50 ` [PATCH v2 12/24] Use all_non_exited_inferiors in infrun.c Pedro Alves
2019-10-17 22:50 ` [PATCH v2 03/24] Make "show remote exec-file" inferior-aware Pedro Alves
2019-10-17 22:50 ` [PATCH v2 10/24] Some get_last_target_status tweaks Pedro Alves
2019-10-17 22:50 ` [PATCH v2 11/24] tfile_target::close: trace_fd can't be -1 Pedro Alves
2019-10-17 22:50 ` [PATCH v2 21/24] Revert 'Remove unused struct serial::name field' Pedro Alves
2019-10-17 22:50 ` [PATCH v2 09/24] switch inferior/thread before calling target methods Pedro Alves
2019-10-17 22:50 ` [PATCH v2 01/24] Preserve selected thread in all-stop w/ background execution Pedro Alves
2019-11-01 13:20   ` Tom Tromey
2019-12-20 17:22     ` Pedro Alves
2019-12-20 18:54       ` Tom Tromey
2019-12-20 18:57         ` Pedro Alves
2019-12-20 18:57           ` Tom Tromey
2019-10-17 22:50 ` [PATCH v2 06/24] Don't check target is running in remote_target::mourn_inferior Pedro Alves
2019-10-17 22:50 ` [PATCH v2 15/24] Avoid another inferior_ptid reference in gdb/remote.c Pedro Alves
2019-10-17 22:51 ` [PATCH v2 18/24] Multi-target support Pedro Alves
2020-01-11  3:12   ` Simon Marchi
2020-01-12  1:58     ` [pushed] Remove last traces of discard_all_inferiors (Re: [PATCH v2 18/24] Multi-target support) Pedro Alves
2020-01-12 20:17   ` [PATCH v2 18/24] Multi-target support Simon Marchi
2020-01-13 15:19     ` Pedro Alves
2020-01-13 16:37       ` Simon Marchi
2020-01-12 22:30   ` Simon Marchi
2020-01-13 15:59     ` Pedro Alves
2020-01-17  4:03   ` Simon Marchi
2020-01-17 16:19     ` Simon Marchi
2020-01-17 15:18   ` Simon Marchi
2020-05-16  8:16   ` Andreas Schwab
2020-05-16 11:33     ` Fix IA-64 GNU/Linux build (Re: [PATCH v2 18/24] Multi-target support) Pedro Alves
2019-10-17 22:51 ` [PATCH v2 04/24] exceptions.c:print_flush: Remove obsolete check Pedro Alves
2019-10-17 22:51 ` [PATCH v2 22/24] Add "info connections" command, "info inferiors" connection number/string Pedro Alves
2019-10-17 22:51 ` [PATCH v2 19/24] Add multi-target tests Pedro Alves
2019-10-17 22:57 ` [PATCH v2 07/24] Delete unnecessary code from kill_command Pedro Alves
2019-10-17 22:57 ` [PATCH v2 05/24] Make target_ops::has_execution take an 'inferior *' instead of a ptid_t Pedro Alves
2019-10-17 22:57 ` [PATCH v2 23/24] Require always-non-stop for multi-target resumptions Pedro Alves
2019-11-01 14:51   ` Tom Tromey
2019-12-30 18:30     ` Pedro Alves [this message]
2019-12-31 20:06       ` Tom Tromey
2019-10-17 22:59 ` [PATCH v2 08/24] Introduce switch_to_inferior_no_thread Pedro Alves
2019-11-07  9:14   ` Paunovic, Aleksandar
2019-12-20 18:50     ` Pedro Alves
2019-12-23 19:30       ` [PATCH] Switch the inferior too in switch_to_program_space_and_thread (Re: [PATCH v2 08/24] Introduce switch_to_inferior_no_thread) Pedro Alves
2020-01-08 15:48         ` Aktemur, Tankut Baris
2020-01-10  2:03           ` Pedro Alves
2020-01-10 11:33             ` Aktemur, Tankut Baris
2020-01-10 12:18               ` Pedro Alves
2020-01-10 13:51                 ` Aktemur, Tankut Baris
2020-01-10 14:41             ` Tom Tromey
2020-01-10 20:03               ` Pedro Alves
2019-10-17 22:59 ` [PATCH v2 20/24] gdbarch-selftests.c: No longer error out if debugging something Pedro Alves
2019-10-17 22:59 ` [PATCH v2 24/24] Multi-target: NEWS and user manual Pedro Alves
2019-10-17 22:59 ` [PATCH v2 13/24] Delete exit_inferior_silent(int pid) Pedro Alves
2019-10-17 23:00 ` [PATCH v2 14/24] Tweak handling of remote errors in response to resumption packet Pedro Alves
2019-10-18 20:23 ` [PATCH v2 00/24] Multi-target support John Baldwin
2019-10-29 19:13   ` Pedro Alves
2020-01-09 19:32     ` John Baldwin
2020-01-09 19:50       ` Pedro Alves
2020-01-10 13:49         ` Aktemur, Tankut Baris
2020-01-10 15:40           ` [PATCH] Switch the inferior before outputting its id in "info inferiors" (Re: [PATCH v2 00/24] Multi-target support) Pedro Alves
2019-10-20 11:41 ` [PATCH v2 00/24] Multi-target support Philippe Waroquiers
2019-10-29 19:56   ` Pedro Alves
2019-11-01 14:56 ` Tom Tromey
2020-01-10 20:13 ` Pedro Alves
2020-08-04  3:30   ` Kevin Buettner
2020-08-06 15:16     ` Pedro Alves
2020-08-06 17:49       ` Tom Tromey
2020-08-07 22:43       ` Kevin Buettner
2020-08-12 18:45         ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20fe7d0b-d6c3-5eb4-9b44-b9cd86f0e576@redhat.com \
    --to=palves@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).