[PATCH 21/23] Add "info connections" command, "info inferiors" connection number/string

Pedro Alves
2019-09-06T23:37:28Z

This commit extends the CLI a bit for multi-target, in three ways.

#1 - New "info connections" command.

This is a new command that lists the open connections (process_stratum
targets). For example, if you're debugging two remote connections, a
couple local/native processes, and a core dump, all at the same time,
you might see something like this:

(gdb) info connections
Num Name Description
1 remote 192.168.0.1:9999 Remote serial target in gdb-specific protocol
2 remote 192.168.0.2:9998 Remote serial target in gdb-specific protocol
* 3 native Native process
4 core Local core dump file

#2 - New "info inferiors" "Connection" column

You'll also see a new matching "Connection" column in "info
inferiors", showing you which connection an inferior is bound to:

(gdb) info inferiors
Num Description Connection Executable
1 process 18526 1 (remote 192.168.0.1:9999) target:/tmp/a.out
2 process 18531 2 (remote 192.168.0.2:9998) target:/tmp/a.out
3 process 19115 3 (native) /tmp/prog1
4 process 6286 4 (core) myprogram
* 5 process 19122 3 (native) /bin/hello

#3 - Makes "add-inferior" show the inferior's target connection

"add-inferior" now shows you the connection you've just bound the
inferior to, which is the current process_stratum target:

(gdb) add-inferior
[New inferior 2]
Added inferior 2 on connection 1 (extended-remote localhost:2346)

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

* Makefile.in (COMMON_SFILES): Add target-connection.c.
* inferior.c (uiout_field_connection): New function.
(print_inferior): Add new "connection-id" column.
(add_inferior_command): Show connection number/string of added
inferior.
* process-stratum-target.h
(process_stratum_target::connection_string): New virtual method.
(process_stratum_target::connection_number): New field.
* remote.c (remote_target::connection_string): New override.
* target-connection.c: New file.
* target-connection.h: New file.
* target.c (decref_target): Remove process_stratum targets from
the connection list.
(target_stack::push): Add process_stratum targets to the
connection list.

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

* gdb.base/kill-detach-inferiors-cmd.exp: Adjust expected output
of "add-inferior".
* gdb.base/quit-live.exp: Likewise.
* gdb.base/remote-exec-file.exp: Likewise.
* gdb.guile/scm-progspace.exp: Likewise.
* gdb.linespec/linespec.exp: Likewise.
* gdb.mi/new-ui-mi-sync.exp: Likewise.
* gdb.mi/user-selected-context-sync.exp: Likewise.
* gdb.multi/multi-target.exp (setup): Add "info connection" and
"info inferiors" tests.
* gdb.multi/remove-inferiors.exp: Adjust expected output of
"add-inferior".
* gdb.multi/watchpoint-multi.exp: Likewise.
* gdb.python/py-inferior.exp: Likewise.
* gdb.server/extended-remote-restart.exp: Likewise.
* gdb.threads/fork-plus-threads.exp: Adjust expected output of
"info inferiors".
* gdb.threads/forking-threads-plus-breakpoint.exp: Likewise.
* gdb.trace/report.exp: Likewise.
---
gdb/Makefile.in | 1 +
gdb/inferior.c | 56 +++++++-
gdb/process-stratum-target.h | 13 ++
gdb/remote.c | 13 ++
gdb/target-connection.c | 156 +++++++++++++++++++++
gdb/target-connection.h | 32 +++++
gdb/target.c | 10 +-
.../gdb.base/kill-detach-inferiors-cmd.exp | 4 +-
gdb/testsuite/gdb.base/quit-live.exp | 2 +-
gdb/testsuite/gdb.base/remote-exec-file.exp | 2 +-
gdb/testsuite/gdb.guile/scm-progspace.exp | 2 +-
gdb/testsuite/gdb.linespec/linespec.exp | 2 +-
gdb/testsuite/gdb.mi/new-ui-mi-sync.exp | 2 +-
.../gdb.mi/user-selected-context-sync.exp | 2 +-
gdb/testsuite/gdb.multi/multi-target.exp | 28 +++-
gdb/testsuite/gdb.multi/remove-inferiors.exp | 2 +-
gdb/testsuite/gdb.multi/watchpoint-multi.exp | 2 +-
gdb/testsuite/gdb.python/py-inferior.exp | 4 +-
.../gdb.server/extended-remote-restart.exp | 18 ++-
gdb/testsuite/gdb.threads/fork-plus-threads.exp | 2 +-
.../forking-threads-plus-breakpoint.exp | 2 +-
gdb/testsuite/gdb.trace/report.exp | 2 +-
22 files changed, 329 insertions(+), 28 deletions(-)
create mode 100644 gdb/target-connection.c
create mode 100644 gdb/target-connection.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index e7e26a44a0..4fa84fa16c 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1119,6 +1119,7 @@ COMMON_SFILES = \
symmisc.c \
symtab.c \
target.c \
+ target-connection.c \
target-dcache.c \
target-descriptions.c \
target-memory.c \
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 6f4f396453..96d38f865d 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -429,6 +429,31 @@ print_selected_inferior (struct ui_out *uiout)
inf->num, inferior_pid_to_str (inf->pid).c_str (), filename);
}

+/* Helper for print_inferior. Returns the 'connection-id' string for
+ PROC_TARGET. */
+
+static std::string
+uiout_field_connection (process_stratum_target *proc_target)
+{
+ if (proc_target == NULL)
+ {
+ return {};
+ }
+ else if (proc_target->connection_string () != NULL)
+ {
+ return string_printf ("%d (%s %s)",
+ proc_target->connection_number,
+ proc_target->shortname (),
+ proc_target->connection_string ());
+ }
+ else
+ {
+ return string_printf ("%d (%s)",
+ proc_target->connection_number,
+ proc_target->shortname ());
+ }
+}
+
/* Prints the list of inferiors and their details on UIOUT. This is a
version of 'info_inferior_command' suitable for use from MI.

@@ -440,6 +465,7 @@ static void
print_inferior (struct ui_out *uiout, const char *requested_inferiors)
{
int inf_count = 0;
+ size_t connection_id_len = 20;

/* Compute number of inferiors we will print. */
for (inferior *inf : all_inferiors ())
@@ -447,6 +473,10 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
if (!number_is_in_list (requested_inferiors, inf->num))
continue;

+ std::string conn = uiout_field_connection (inf->process_target ());
+ if (connection_id_len < conn.size ())
+ connection_id_len = conn.size ();
+
++inf_count;
}

@@ -456,10 +486,12 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
return;
}

- ui_out_emit_table table_emitter (uiout, 4, inf_count, "inferiors");
+ ui_out_emit_table table_emitter (uiout, 5, inf_count, "inferiors");
uiout->table_header (1, ui_left, "current", "");
uiout->table_header (4, ui_left, "number", "Num");
uiout->table_header (17, ui_left, "target-id", "Description");
+ uiout->table_header (connection_id_len, ui_left,
+ "connection-id", "Connection");
uiout->table_header (17, ui_left, "exec", "Executable");

uiout->table_body ();
@@ -479,6 +511,9 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)

uiout->field_string ("target-id", inferior_pid_to_str (inf->pid));

+ std::string conn = uiout_field_connection (inf->process_target ());
+ uiout->field_string ("connection-id", conn.c_str ());
+
if (inf->pspace->pspace_exec_filename != NULL)
uiout->field_string ("exec", inf->pspace->pspace_exec_filename);
else
@@ -713,9 +748,22 @@ switch_to_inferior_and_push_target (inferior *new_inf,

/* Reuse the target for new inferior. */
if (!no_connection && proc_target != NULL)
- push_target (proc_target);
-
- printf_filtered (_("Added inferior %d\n"), new_inf->num);
+ {
+ push_target (proc_target);
+ if (proc_target->connection_string () != NULL)
+ printf_filtered (_("Added inferior %d on connection %d (%s %s)\n"),
+ new_inf->num,
+ proc_target->connection_number,
+ proc_target->shortname (),
+ proc_target->connection_string ());
+ else
+ printf_filtered (_("Added inferior %d on connection %d (%s)\n"),
+ new_inf->num,
+ proc_target->connection_number,
+ proc_target->shortname ());
+ }
+ else
+ printf_filtered (_("Added inferior %d\n"), new_inf->num);
}

/* add-inferior [-copies N] [-exec FILENAME] [-no-connection] */
diff --git a/gdb/process-stratum-target.h b/gdb/process-stratum-target.h
index 6081c0a927..53e1c6a618 100644
--- a/gdb/process-stratum-target.h
+++ b/gdb/process-stratum-target.h
@@ -31,6 +31,16 @@ public:

strata stratum () const final override { return process_stratum; }

+ /* Return a string representation of this target's open connection.
+ This string is used to distinguish different instances of a given
+ target type. For example, when remote debugging, the target is
+ called "remote", but since we may have more than one remote
+ target open, connection_string() returns the connection serial
+ connection name, e.g., "localhost:10001", "192.168.0.1:20000",
+ etc. This string is shown in several places, e.g., in "info
+ connections" and "info inferiors". */
+ virtual const char *connection_string () { return nullptr; }
+
/* We must default these because they must be implemented by any
target that can run. */
bool can_async_p () override { return false; }
@@ -58,6 +68,9 @@ public:
stop events for all known threads, because any of those threads
may have spawned new threads we haven't heard of yet. */
bool threads_executing = false;
+
+ /* The connection number. Visible in "info connections". */
+ int connection_number = 0;
};

/* Downcast TARGET to process_stratum_target. */
diff --git a/gdb/remote.c b/gdb/remote.c
index 168fff3047..ff75204ee8 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -404,6 +404,8 @@ public:
const target_info &info () const override
{ return remote_target_info; }

+ const char *connection_string () override;
+
thread_control_capabilities get_thread_control_capabilities () override
{ return tc_schedlock; }

@@ -4860,6 +4862,17 @@ remote_target::start_remote (int from_tty, int extended_p)
insert_breakpoints ();
}

+const char *
+remote_target::connection_string ()
+{
+ remote_state *rs = get_remote_state ();
+
+ if (rs->remote_desc->name != NULL)
+ return rs->remote_desc->name;
+ else
+ return NULL;
+}
+
/* Open a connection to a remote debugger.
NAME is the filename used for communication. */

diff --git a/gdb/target-connection.c b/gdb/target-connection.c
new file mode 100644
index 0000000000..f13e649977
--- /dev/null
+++ b/gdb/target-connection.c
@@ -0,0 +1,156 @@
+/* List of target connections for GDB.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "target-connection.h"
+
+#include
+
+#include "inferior.h"
+#include "target.h"
+
+/* A map between connection number and representative process_stratum
+ target. */
+static std::map<int, process_stratum_target *> process_targets;
+
+/* The highest connection number ever given to a target. */
+static int highest_target_connection_num;
+
+/* See target-connection.h. */
+
+void
+connection_list_add (process_stratum_target *t)
+{
+ if (t->connection_number == 0)
+ {
+ t->connection_number = ++highest_target_connection_num;
+ process_targets[t->connection_number] = t;
+ }
+}
+
+/* See target-connection.h. */
+
+void
+connection_list_remove (process_stratum_target *t)
+{
+ process_targets.erase (t->connection_number);
+ 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. */
+
+static std::string
+make_target_connection_string (process_stratum_target *t)
+{
+ if (t->connection_string () != NULL)
+ return string_printf ("%s %s", t->shortname (),
+ t->connection_string ());
+ else
+ return t->shortname ();
+}
+
+/* Prints the list of target connections and their details on UIOUT.
+
+ If REQUESTED_CONNECTIONS is not NULL, it's a list of GDB ids of the
+ target connections that should be printed. Otherwise, all target
+ connections are printed. */
+
+static void
+print_connection (struct ui_out *uiout, const char *requested_connections)
+{
+ int count = 0;
+ size_t name_len = 0;
+
+ /* Compute number of lines we will print. */
+ for (const auto &it : process_targets)
+ {
+ if (!number_is_in_list (requested_connections, it.first))
+ continue;
+
+ ++count;
+
+ process_stratum_target *t = it.second;
+
+ size_t l = strlen (t->shortname ());
+ if (t->connection_string () != NULL)
+ l += 1 + strlen (t->connection_string ());
+
+ if (l > name_len)
+ name_len = l;
+ }
+
+ if (count == 0)
+ {
+ uiout->message (_("No connections.\n"));
+ return;
+ }
+
+ ui_out_emit_table table_emitter (uiout, 4, process_targets.size (),
+ "connections");
+
+ uiout->table_header (1, ui_left, "current", "");
+ uiout->table_header (4, ui_left, "number", "Num");
+ uiout->table_header (name_len + 1, ui_left, "name", "Name");
+ uiout->table_header (17, ui_left, "description", "Description");
+
+ uiout->table_body ();
+
+ for (const auto &it : process_targets)
+ {
+ process_stratum_target *t = it.second;
+
+ if (!number_is_in_list (requested_connections, t->connection_number))
+ continue;
+
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
+
+ if (current_inferior ()->process_target () == t)
+ uiout->field_string ("current", "*");
+ else
+ uiout->field_skip ("current");
+
+ uiout->field_signed ("number", t->connection_number);
+
+ uiout->field_string ("name", make_target_connection_string (t).c_str ());
+
+ uiout->field_string ("description", t->longname ());
+
+ uiout->text ("\n");
+ }
+}
+
+/* The "info connections" command. */
+
+static void
+info_connections_command (const char *args, int from_tty)
+{
+ print_connection (current_uiout, args);
+}
+
+void
+_initialize_target_connection ()
+{
+ add_info ("connections", info_connections_command,
+ _("\
+Names of target connections being debugged.\n\
+Shows the list of targets currently in use as well as their description."));
+}
diff --git a/gdb/target-connection.h b/gdb/target-connection.h
new file mode 100644
index 0000000000..0e2dc128d8
--- /dev/null
+++ b/gdb/target-connection.h
@@ -0,0 +1,32 @@
+/* List of target connections for GDB.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef TARGET_CONNECTION_H
+#define TARGET_CONNECTION_H
+
+struct process_stratum_target;
+
+/* Add a process target to the connection list, if not already
+ added. */
+void connection_list_add (process_stratum_target *t);
+
+/* Remove a process target from the connection list. */
+void connection_list_remove (process_stratum_target *t);
+
+#endif /* TARGET_CONNECTION_H */
diff --git a/gdb/target.c b/gdb/target.c
index 541b95bc10..ba01148d7a 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -49,6 +49,7 @@
#include "gdbsupport/byte-vector.h"
#include "terminal.h"
#include <unordered_map>
+#include "target-connection.h"

static void generic_tls_error (void) ATTRIBUTE_NORETURN;

@@ -561,7 +562,11 @@ decref_target (target_ops *t)
{
t->decref ();
if (t->refcount () == 0)
- target_close (t);
+ {
+ if (t->stratum () == process_stratum)
+ connection_list_remove (as_process_stratum_target (t));
+ target_close (t);
+ }
}

/* See target.h. */
@@ -573,6 +578,9 @@ target_stack::push (target_ops *t)

strata stratum = t->stratum ();

+ if (stratum == process_stratum)
+ connection_list_add (as_process_stratum_target (t));
+
/* If there's already a target at this stratum, remove it. */

if (m_stack[stratum] != NULL)
diff --git a/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp b/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp
index 63045cb504..bd50a60c7f 100644
--- a/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp
+++ b/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp
@@ -32,7 +32,7 @@ if [prepare_for_testing "failed to prepare" $executable] {
runto_main

# Add another forked inferior process.
-gdb_test "add-inferior" "Added inferior 2" "add inferior 2"
+gdb_test "add-inferior" "Added inferior 2 on target .*" "add inferior 2"
gdb_test "inferior 2" "Switching to inferior 2.*"
gdb_test "file $binfile" "Reading symbols from .*" "load binary"
gdb_test "start" "Temporary breakpoint.*Starting program.*"
@@ -40,7 +40,7 @@ gdb_test "start" "Temporary breakpoint.*Starting program.*"
# Add an attached inferior process.
set test_spawn_id [spawn_wait_for_attach $binfile]
set test_pid [spawn_id_get_pid $test_spawn_id]
-gdb_test "add-inferior" "Added inferior 3" "add inferior 3"
+gdb_test "add-inferior" "Added inferior 3 on connection .*" "add inferior 3"
gdb_test "inferior 3" "Switching to inferior 3.*"
gdb_test "attach $test_pid" "Attaching to process.*" "attach to pid"

diff --git a/gdb/testsuite/gdb.base/quit-live.exp b/gdb/testsuite/gdb.base/quit-live.exp
index c0eba44d43..7b23a9c013 100644
--- a/gdb/testsuite/gdb.base/quit-live.exp
+++ b/gdb/testsuite/gdb.base/quit-live.exp
@@ -120,7 +120,7 @@ proc quit_with_live_inferior {appear_how extra_inferior quit_how} {
}

if {$extra_inferior} {
- gdb_test "add-inferior" "Added inferior 2*" \
+ gdb_test "add-inferior" "Added inferior 2 on connection .*" \
"add empty inferior 2"
gdb_test "inferior 2" "Switching to inferior 2.*" \
"switch to inferior 2"
diff --git a/gdb/testsuite/gdb.base/remote-exec-file.exp b/gdb/testsuite/gdb.base/remote-exec-file.exp
index 3db009b830..6af8afcc5a 100644
--- a/gdb/testsuite/gdb.base/remote-exec-file.exp
+++ b/gdb/testsuite/gdb.base/remote-exec-file.exp
@@ -27,7 +27,7 @@ with_test_prefix "set inf 1" {

# Set remote exec-file in inferior 2.
with_test_prefix "set inf 2" {
- gdb_test "add-inferior" "Added inferior 2" "add inferior 2"
+ gdb_test "add-inferior" "Added inferior 2.*" "add inferior 2"
gdb_test "inferior 2" "Switching to inferior 2.*"
gdb_test_no_output "set remote exec-file prog2"
}
diff --git a/gdb/testsuite/gdb.guile/scm-progspace.exp b/gdb/testsuite/gdb.guile/scm-progspace.exp
index cb8384f83d..19520943c0 100644
--- a/gdb/testsuite/gdb.guile/scm-progspace.exp
+++ b/gdb/testsuite/gdb.guile/scm-progspace.exp
@@ -73,7 +73,7 @@ with_test_prefix "program unloaded" {
# deleted. We need to, for example, delete an inferior to get the progspace
# to go away.

-gdb_test "add-inferior" "Added inferior 2" "create new inferior"
+gdb_test "add-inferior" "Added inferior 2.*" "create new inferior"
gdb_test "inferior 2" ".*" "switch to new inferior"
gdb_test_no_output "remove-inferiors 1" "remove first inferior"

diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp
index 45982ddeff..08be8f606f 100644
--- a/gdb/testsuite/gdb.linespec/linespec.exp
+++ b/gdb/testsuite/gdb.linespec/linespec.exp
@@ -201,7 +201,7 @@ gdb_test "break lspec.h:$line" \
# Multi-inferior tests.
#

-gdb_test "add-inferior" "Added inferior 2" \
+gdb_test "add-inferior" "Added inferior 2.*" \
"add inferior for linespec tests"

gdb_test "inferior 2" "Switching to inferior 2 .*" \
diff --git a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
index 5560a8be96..7eb4fb3716 100644
--- a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
+++ b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
@@ -83,7 +83,7 @@ proc do_test {sync_command} {
# in the separate MI UI. Note the "run" variant usually triggers
# =thread-group-started/=thread-created/=library-loaded as well.
with_spawn_id $gdb_main_spawn_id {
- gdb_test "add-inferior" "Added inferior 2"
+ gdb_test "add-inferior" "Added inferior 2 on connection .*"
}

# Interrupt the program.
diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
index 621b4c5163..19dd4c9493 100644
--- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
+++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
@@ -415,7 +415,7 @@ proc_with_prefix test_setup { mode } {
# Add the second inferior now. While this is not mandatory, it allows
# us to assume that per-inferior thread numbering will be used,
# simplifying test_continue_to_start a bit (Thread 1.2 and not Thread 2).
- gdb_test "add-inferior" "Added inferior 2" "add inferior 2"
+ gdb_test "add-inferior" "Added inferior 2 on connection .*" "add inferior 2"

# Prepare the first inferior for the test.
test_continue_to_start $mode 1
diff --git a/gdb/testsuite/gdb.multi/multi-target.exp b/gdb/testsuite/gdb.multi/multi-target.exp
index 3b71e7446b..78a43d8c2e 100644
--- a/gdb/testsuite/gdb.multi/multi-target.exp
+++ b/gdb/testsuite/gdb.multi/multi-target.exp
@@ -137,8 +137,34 @@ proc setup {non-stop} {
return 0
}

+ set ws "\[ \t\]+"
+ global decimal
+
+ # Test "info connections" and "info inferior"'s "Connection"
+ # column, while at it.
+
+ gdb_test "info connections" \
+ [multi_line \
+ "Num${ws}Name${ws}Description${ws}" \
+ " 1${ws}native${ws}Native process${ws}" \
+ " 2${ws}extended-remote localhost:$decimal${ws}Extended remote serial target in gdb-specific protocol${ws}" \
+ " 3${ws}core${ws}Local core dump file${ws}" \
+ " 4${ws}extended-remote localhost:$decimal${ws}Extended remote serial target in gdb-specific protocol${ws}" \
+ "\\* 5${ws}core${ws}Local core dump file${ws}" \
+ ]
+
+ gdb_test "info inferiors" \
+ [multi_line \
+ "Num${ws}Description${ws}Connection${ws}Executable${ws}" \
+ " 1${ws}process ${decimal}${ws}1 \\(native\\)${ws}${binfile}${ws}" \
+ " 2${ws}process ${decimal}${ws}2 \\(extended-remote localhost:$decimal\\)${ws}${binfile}${ws}" \
+ " 3${ws}process ${decimal}${ws}3 \\(core\\)${ws}${binfile}${ws}" \
+ " 4${ws}process ${decimal}${ws}1 \\(native\\)${ws}${binfile}${ws}" \
+ " 5${ws}process ${decimal}${ws}4 \\(extended-remote localhost:$decimal\\)${ws}${binfile}${ws}" \
+ "\\* 6${ws}process ${decimal}${ws}5 \\(core\\)${ws}${binfile}${ws}" \
+ ]
+
# For debugging.
- gdb_test "info inferiors" ".*"
gdb_test "info threads" ".*"

# Make "continue" resume all inferiors.
diff --git a/gdb/testsuite/gdb.multi/remove-inferiors.exp b/gdb/testsuite/gdb.multi/remove-inferiors.exp
index 18f6c90225..ef3def7b5b 100644
--- a/gdb/testsuite/gdb.multi/remove-inferiors.exp
+++ b/gdb/testsuite/gdb.multi/remove-inferiors.exp
@@ -26,7 +26,7 @@ proc switch_to_inferior { num message } {
}

proc add_inferior { expected_num message } {
- gdb_test "add-inferior" "Added inferior ${expected_num}" "${message}"
+ gdb_test "add-inferior" "Added inferior ${expected_num}( on connection .*)?" "${message}"
}

proc test_remove_inferiors { } {
diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
index b0f47db374..f3f9ca58fc 100644
--- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp
+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
@@ -53,7 +53,7 @@ if [support_displaced_stepping] {
gdb_breakpoint main {temporary}
gdb_test "run" "Temporary breakpoint.* main .*" "start to main inferior 1"

-gdb_test "add-inferior" "Added inferior 2" "add inferior 2"
+gdb_test "add-inferior" "Added inferior 2 on connection .*" "add inferior 2"
gdb_test "inferior 2" "witching to inferior 2 .*" "switch to inferior 2, first time"
gdb_load $binfile

diff --git a/gdb/testsuite/gdb.python/py-inferior.exp b/gdb/testsuite/gdb.python/py-inferior.exp
index 72ec1f2186..a4839c83d6 100644
--- a/gdb/testsuite/gdb.python/py-inferior.exp
+++ b/gdb/testsuite/gdb.python/py-inferior.exp
@@ -279,7 +279,7 @@ with_test_prefix "selected_inferior" {
gdb_test "inferior 1" ".*" "switch to first inferior"
gdb_test "py print (gdb.selected_inferior().num)" "1" "first inferior selected"

- gdb_test "add-inferior" "Added inferior 3" "create new inferior"
+ gdb_test "add-inferior" "Added inferior 3 on connection .*" "create new inferior"
gdb_test "inferior 3" ".*" "switch to third inferior"
gdb_test "py print (gdb.selected_inferior().num)" "3" "third inferior selected"
gdb_test "inferior 1" ".*" "switch back to first inferior"
@@ -288,7 +288,7 @@ with_test_prefix "selected_inferior" {

# Test repr()/str()
with_test_prefix "__repr__" {
- gdb_test "add-inferior" "Added inferior 4" "add inferior 4"
+ gdb_test "add-inferior" "Added inferior 4 on connection .*" "add inferior 4"
gdb_py_test_silent_cmd "python infs = gdb.inferiors()" "get inferior list" 1
gdb_test "python print (infs\[0\])" "<gdb.Inferior num=1, pid=$decimal>"
gdb_test "python print (infs)" \
diff --git a/gdb/testsuite/gdb.server/extended-remote-restart.exp b/gdb/testsuite/gdb.server/extended-remote-restart.exp
index c78342c010..c1010a9358 100644
--- a/gdb/testsuite/gdb.server/extended-remote-restart.exp
+++ b/gdb/testsuite/gdb.server/extended-remote-restart.exp
@@ -88,12 +88,16 @@ proc test_reload { do_kill_p follow_child_p } {
gdb_breakpoint "breakpt"
gdb_continue_to_breakpoint "breakpt"

- # Check we have the expected inferiors.
+ set ws "\[ \t\]+"
+ set any_re "\[^\r\n\]+"
+ set connection_re $any_re
+ set executable_re $any_re
+
gdb_test "info inferiors" \
[multi_line \
- " Num Description Executable.*" \
- "${parent_prefix} 1 +${live_inf_ptn} \[^\r\n\]+" \
- "${child_prefix} 2 +${live_inf_ptn} \[^\r\n\]+" ] \
+ " Num${ws}Description${ws}Connection${ws}Executable${ws}" \
+ "${parent_prefix} 1${ws}${live_inf_ptn}${ws}${connection_re}${executable_re}" \
+ "${child_prefix} 2${ws}${live_inf_ptn}${ws}${connection_re}${executable_re}" ] \
"Check inferiors at breakpoint"

if { $do_kill_p } {
@@ -107,9 +111,9 @@ proc test_reload { do_kill_p follow_child_p } {
# Check the first inferior really did die.
gdb_test "info inferiors" \
[multi_line \
- " Num Description Executable.*" \
- "${parent_prefix} 1 +${parent_inf_after_kill_ptn} \[^\r\n\]+" \
- "${child_prefix} 2 +${child_inf_after_kill_ptn} \[^\r\n\]+" ] \
+ " Num${ws}Description${ws}Connection${ws}Executable${ws}" \
+ "${parent_prefix} 1${ws}${parent_inf_after_kill_ptn}${ws}${connection_re}${executable_re}" \
+ "${child_prefix} 2${ws}${child_inf_after_kill_ptn}${ws}${connection_re}${executable_re}" ] \
"Check inferior was killed"
}

diff --git a/gdb/testsuite/gdb.threads/fork-plus-threads.exp b/gdb/testsuite/gdb.threads/fork-plus-threads.exp
index 340a8df266..d488bb9d39 100644
--- a/gdb/testsuite/gdb.threads/fork-plus-threads.exp
+++ b/gdb/testsuite/gdb.threads/fork-plus-threads.exp
@@ -109,7 +109,7 @@ proc do_test { detach_on_fork } {
"no threads left"

gdb_test "info inferiors" \
- "Num\[ \t\]+Description\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \
+ "Num\[ \t\]+Description\[ \t\]+Connection\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \
"only inferior 1 left"
}

diff --git a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
index 1d1378234e..6d24af401b 100644
--- a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
+++ b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
@@ -142,7 +142,7 @@ proc do_test { cond_bp_target detach_on_fork displaced } {
"no threads left"

gdb_test "info inferiors" \
- "Num\[ \t\]+Description\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \
+ "Num\[ \t\]+Description\[ \t\]+Connection\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \
"only inferior 1 left"
}

diff --git a/gdb/testsuite/gdb.trace/report.exp b/gdb/testsuite/gdb.trace/report.exp
index c847ab0c5b..2949f1bb0d 100644
--- a/gdb/testsuite/gdb.trace/report.exp
+++ b/gdb/testsuite/gdb.trace/report.exp
@@ -391,7 +391,7 @@ proc use_collected_data { data_source } {
# There is always a thread of an inferior, either a live one or
# a faked one.
gdb_test "info threads" "\\* ${decimal} (process|Thread) \[0-9\.\]+\[ \t\].*"
- gdb_test "info inferiors" "\\* 1 process ${decimal} \[ \t\]+${binfile}.*"
+ gdb_test "info inferiors" "\\* 1 process ${decimal} \[ \t\]+\[^\r\n\]*\[ \t\]+${binfile}.*"
}
}

--
2.14.5