@@ -30,6 +30,7 @@
#include "gdbcmd.h"
#include "cli/cli-script.h"
#include "target.h"
+#include "target-connection.h"
#include "gdbthread.h"
#include "annotate.h"
#include "symfile.h"
@@ -2888,6 +2889,56 @@ commit_resume_all_targets ()
}
}
+/* Check that all the targets we're about to resume are in non-stop
+ mode, since that's the only way we support handling events from
+ multiple targets simultaneously. */
+
+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.
@@ -2938,6 +2989,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
@@ -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)
@@ -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 */