Add "info connections" command, "info inferiors" connection number/string
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 What 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: 2020-01-10 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: 2020-01-10 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.
This commit is contained in:
parent
4f83758119
commit
121b3efd49
@ -1,3 +1,21 @@
|
|||||||
|
2020-01-10 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.
|
||||||
|
|
||||||
2020-01-10 Pedro Alves <palves@redhat.com>
|
2020-01-10 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
Revert:
|
Revert:
|
||||||
|
@ -1140,6 +1140,7 @@ COMMON_SFILES = \
|
|||||||
symmisc.c \
|
symmisc.c \
|
||||||
symtab.c \
|
symtab.c \
|
||||||
target.c \
|
target.c \
|
||||||
|
target-connection.c \
|
||||||
target-dcache.c \
|
target-dcache.c \
|
||||||
target-descriptions.c \
|
target-descriptions.c \
|
||||||
target-memory.c \
|
target-memory.c \
|
||||||
|
@ -428,6 +428,31 @@ print_selected_inferior (struct ui_out *uiout)
|
|||||||
inf->num, inferior_pid_to_str (inf->pid).c_str (), filename);
|
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
|
/* Prints the list of inferiors and their details on UIOUT. This is a
|
||||||
version of 'info_inferior_command' suitable for use from MI.
|
version of 'info_inferior_command' suitable for use from MI.
|
||||||
|
|
||||||
@ -439,6 +464,7 @@ static void
|
|||||||
print_inferior (struct ui_out *uiout, const char *requested_inferiors)
|
print_inferior (struct ui_out *uiout, const char *requested_inferiors)
|
||||||
{
|
{
|
||||||
int inf_count = 0;
|
int inf_count = 0;
|
||||||
|
size_t connection_id_len = 20;
|
||||||
|
|
||||||
/* Compute number of inferiors we will print. */
|
/* Compute number of inferiors we will print. */
|
||||||
for (inferior *inf : all_inferiors ())
|
for (inferior *inf : all_inferiors ())
|
||||||
@ -446,6 +472,10 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
|
|||||||
if (!number_is_in_list (requested_inferiors, inf->num))
|
if (!number_is_in_list (requested_inferiors, inf->num))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
std::string conn = uiout_field_connection (inf->process_target ());
|
||||||
|
if (connection_id_len < conn.size ())
|
||||||
|
connection_id_len = conn.size ();
|
||||||
|
|
||||||
++inf_count;
|
++inf_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,10 +485,12 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
|
|||||||
return;
|
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 (1, ui_left, "current", "");
|
||||||
uiout->table_header (4, ui_left, "number", "Num");
|
uiout->table_header (4, ui_left, "number", "Num");
|
||||||
uiout->table_header (17, ui_left, "target-id", "Description");
|
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_header (17, ui_left, "exec", "Executable");
|
||||||
|
|
||||||
uiout->table_body ();
|
uiout->table_body ();
|
||||||
@ -478,6 +510,9 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
|
|||||||
|
|
||||||
uiout->field_string ("target-id", inferior_pid_to_str (inf->pid));
|
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)
|
if (inf->pspace->pspace_exec_filename != NULL)
|
||||||
uiout->field_string ("exec", inf->pspace->pspace_exec_filename);
|
uiout->field_string ("exec", inf->pspace->pspace_exec_filename);
|
||||||
else
|
else
|
||||||
@ -712,9 +747,22 @@ switch_to_inferior_and_push_target (inferior *new_inf,
|
|||||||
|
|
||||||
/* Reuse the target for new inferior. */
|
/* Reuse the target for new inferior. */
|
||||||
if (!no_connection && proc_target != NULL)
|
if (!no_connection && proc_target != NULL)
|
||||||
push_target (proc_target);
|
{
|
||||||
|
push_target (proc_target);
|
||||||
printf_filtered (_("Added inferior %d\n"), new_inf->num);
|
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] */
|
/* add-inferior [-copies N] [-exec FILENAME] [-no-connection] */
|
||||||
|
@ -31,6 +31,16 @@ public:
|
|||||||
|
|
||||||
strata stratum () const final override { return process_stratum; }
|
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
|
/* We must default these because they must be implemented by any
|
||||||
target that can run. */
|
target that can run. */
|
||||||
bool can_async_p () override { return false; }
|
bool can_async_p () override { return false; }
|
||||||
@ -58,6 +68,9 @@ public:
|
|||||||
stop events for all known threads, because any of those threads
|
stop events for all known threads, because any of those threads
|
||||||
may have spawned new threads we haven't heard of yet. */
|
may have spawned new threads we haven't heard of yet. */
|
||||||
bool threads_executing = false;
|
bool threads_executing = false;
|
||||||
|
|
||||||
|
/* The connection number. Visible in "info connections". */
|
||||||
|
int connection_number = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Downcast TARGET to process_stratum_target. */
|
/* Downcast TARGET to process_stratum_target. */
|
||||||
|
13
gdb/remote.c
13
gdb/remote.c
@ -406,6 +406,8 @@ public:
|
|||||||
const target_info &info () const override
|
const target_info &info () const override
|
||||||
{ return remote_target_info; }
|
{ return remote_target_info; }
|
||||||
|
|
||||||
|
const char *connection_string () override;
|
||||||
|
|
||||||
thread_control_capabilities get_thread_control_capabilities () override
|
thread_control_capabilities get_thread_control_capabilities () override
|
||||||
{ return tc_schedlock; }
|
{ return tc_schedlock; }
|
||||||
|
|
||||||
@ -4853,6 +4855,17 @@ remote_target::start_remote (int from_tty, int extended_p)
|
|||||||
insert_breakpoints ();
|
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.
|
/* Open a connection to a remote debugger.
|
||||||
NAME is the filename used for communication. */
|
NAME is the filename used for communication. */
|
||||||
|
|
||||||
|
162
gdb/target-connection.c
Normal file
162
gdb/target-connection.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/* List of target connections for GDB.
|
||||||
|
|
||||||
|
Copyright (C) 2017-2020 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 <map>
|
||||||
|
|
||||||
|
#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 what_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 > what_len)
|
||||||
|
what_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");
|
||||||
|
/* The text in the "what" column may include spaces. Add one extra
|
||||||
|
space to visually separate the What and Description columns a
|
||||||
|
little better. Compare:
|
||||||
|
"* 1 remote :9999 Remote serial target in gdb-specific protocol"
|
||||||
|
"* 1 remote :9999 Remote serial target in gdb-specific protocol"
|
||||||
|
*/
|
||||||
|
uiout->table_header (what_len + 1, ui_left, "what", "What");
|
||||||
|
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 ("what", 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,
|
||||||
|
_("\
|
||||||
|
Target connections in use.\n\
|
||||||
|
Shows the list of target connections currently in use."));
|
||||||
|
}
|
32
gdb/target-connection.h
Normal file
32
gdb/target-connection.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* List of target connections for GDB.
|
||||||
|
|
||||||
|
Copyright (C) 2017-2020 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 */
|
10
gdb/target.c
10
gdb/target.c
@ -49,6 +49,7 @@
|
|||||||
#include "gdbsupport/byte-vector.h"
|
#include "gdbsupport/byte-vector.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include "target-connection.h"
|
||||||
|
|
||||||
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
|
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
@ -561,7 +562,11 @@ decref_target (target_ops *t)
|
|||||||
{
|
{
|
||||||
t->decref ();
|
t->decref ();
|
||||||
if (t->refcount () == 0)
|
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. */
|
/* See target.h. */
|
||||||
@ -573,6 +578,9 @@ target_stack::push (target_ops *t)
|
|||||||
|
|
||||||
strata stratum = t->stratum ();
|
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 there's already a target at this stratum, remove it. */
|
||||||
|
|
||||||
if (m_stack[stratum] != NULL)
|
if (m_stack[stratum] != NULL)
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
2020-01-10 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.
|
||||||
|
|
||||||
2020-01-10 Pedro Alves <palves@redhat.com>
|
2020-01-10 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* gdb.multi/multi-target.c: New file.
|
* gdb.multi/multi-target.c: New file.
|
||||||
|
@ -32,7 +32,7 @@ if [prepare_for_testing "failed to prepare" $executable] {
|
|||||||
runto_main
|
runto_main
|
||||||
|
|
||||||
# Add another forked inferior process.
|
# Add another forked inferior process.
|
||||||
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" "Switching to inferior 2.*"
|
gdb_test "inferior 2" "Switching to inferior 2.*"
|
||||||
gdb_test "file $binfile" "Reading symbols from .*" "load binary"
|
gdb_test "file $binfile" "Reading symbols from .*" "load binary"
|
||||||
gdb_test "start" "Temporary breakpoint.*Starting program.*"
|
gdb_test "start" "Temporary breakpoint.*Starting program.*"
|
||||||
@ -40,7 +40,7 @@ gdb_test "start" "Temporary breakpoint.*Starting program.*"
|
|||||||
# Add an attached inferior process.
|
# Add an attached inferior process.
|
||||||
set test_spawn_id [spawn_wait_for_attach $binfile]
|
set test_spawn_id [spawn_wait_for_attach $binfile]
|
||||||
set test_pid [spawn_id_get_pid $test_spawn_id]
|
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 "inferior 3" "Switching to inferior 3.*"
|
||||||
gdb_test "attach $test_pid" "Attaching to process.*" "attach to pid"
|
gdb_test "attach $test_pid" "Attaching to process.*" "attach to pid"
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ proc quit_with_live_inferior {appear_how extra_inferior quit_how} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if {$extra_inferior} {
|
if {$extra_inferior} {
|
||||||
gdb_test "add-inferior" "Added inferior 2*" \
|
gdb_test "add-inferior" "Added inferior 2 on connection .*" \
|
||||||
"add empty inferior 2"
|
"add empty inferior 2"
|
||||||
gdb_test "inferior 2" "Switching to inferior 2.*" \
|
gdb_test "inferior 2" "Switching to inferior 2.*" \
|
||||||
"switch to inferior 2"
|
"switch to inferior 2"
|
||||||
|
@ -27,7 +27,7 @@ with_test_prefix "set inf 1" {
|
|||||||
|
|
||||||
# Set remote exec-file in inferior 2.
|
# Set remote exec-file in inferior 2.
|
||||||
with_test_prefix "set inf 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 "inferior 2" "Switching to inferior 2.*"
|
||||||
gdb_test_no_output "set remote exec-file prog2"
|
gdb_test_no_output "set remote exec-file prog2"
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ with_test_prefix "program unloaded" {
|
|||||||
# deleted. We need to, for example, delete an inferior to get the progspace
|
# deleted. We need to, for example, delete an inferior to get the progspace
|
||||||
# to go away.
|
# 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 "inferior 2" ".*" "switch to new inferior"
|
||||||
gdb_test_no_output "remove-inferiors 1" "remove first inferior"
|
gdb_test_no_output "remove-inferiors 1" "remove first inferior"
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ gdb_test "break lspec.h:$line" \
|
|||||||
# Multi-inferior tests.
|
# Multi-inferior tests.
|
||||||
#
|
#
|
||||||
|
|
||||||
gdb_test "add-inferior" "Added inferior 2" \
|
gdb_test "add-inferior" "Added inferior 2.*" \
|
||||||
"add inferior for linespec tests"
|
"add inferior for linespec tests"
|
||||||
|
|
||||||
gdb_test "inferior 2" "Switching to inferior 2 .*" \
|
gdb_test "inferior 2" "Switching to inferior 2 .*" \
|
||||||
|
@ -83,7 +83,7 @@ proc do_test {sync_command} {
|
|||||||
# in the separate MI UI. Note the "run" variant usually triggers
|
# in the separate MI UI. Note the "run" variant usually triggers
|
||||||
# =thread-group-started/=thread-created/=library-loaded as well.
|
# =thread-group-started/=thread-created/=library-loaded as well.
|
||||||
with_spawn_id $gdb_main_spawn_id {
|
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.
|
# Interrupt the program.
|
||||||
|
@ -415,7 +415,7 @@ proc_with_prefix test_setup { mode } {
|
|||||||
# Add the second inferior now. While this is not mandatory, it allows
|
# Add the second inferior now. While this is not mandatory, it allows
|
||||||
# us to assume that per-inferior thread numbering will be used,
|
# 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).
|
# 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.
|
# Prepare the first inferior for the test.
|
||||||
test_continue_to_start $mode 1
|
test_continue_to_start $mode 1
|
||||||
|
@ -137,8 +137,34 @@ proc setup {non-stop} {
|
|||||||
return 0
|
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}What${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.
|
# For debugging.
|
||||||
gdb_test "info inferiors" ".*"
|
|
||||||
gdb_test "info threads" ".*"
|
gdb_test "info threads" ".*"
|
||||||
|
|
||||||
# Make "continue" resume all inferiors.
|
# Make "continue" resume all inferiors.
|
||||||
|
@ -26,7 +26,7 @@ proc switch_to_inferior { num message } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc add_inferior { expected_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 { } {
|
proc test_remove_inferiors { } {
|
||||||
|
@ -53,7 +53,7 @@ if [support_displaced_stepping] {
|
|||||||
gdb_breakpoint main {temporary}
|
gdb_breakpoint main {temporary}
|
||||||
gdb_test "run" "Temporary breakpoint.* main .*" "start to main inferior 1"
|
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_test "inferior 2" "witching to inferior 2 .*" "switch to inferior 2, first time"
|
||||||
gdb_load $binfile
|
gdb_load $binfile
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ with_test_prefix "selected_inferior" {
|
|||||||
gdb_test "inferior 1" ".*" "switch to first inferior"
|
gdb_test "inferior 1" ".*" "switch to first inferior"
|
||||||
gdb_test "py print (gdb.selected_inferior().num)" "1" "first inferior selected"
|
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 "inferior 3" ".*" "switch to third inferior"
|
||||||
gdb_test "py print (gdb.selected_inferior().num)" "3" "third inferior selected"
|
gdb_test "py print (gdb.selected_inferior().num)" "3" "third inferior selected"
|
||||||
gdb_test "inferior 1" ".*" "switch back to first inferior"
|
gdb_test "inferior 1" ".*" "switch back to first inferior"
|
||||||
@ -288,7 +288,7 @@ with_test_prefix "selected_inferior" {
|
|||||||
|
|
||||||
# Test repr()/str()
|
# Test repr()/str()
|
||||||
with_test_prefix "__repr__" {
|
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_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\[0\])" "<gdb.Inferior num=1, pid=$decimal>"
|
||||||
gdb_test "python print (infs)" \
|
gdb_test "python print (infs)" \
|
||||||
|
@ -88,12 +88,16 @@ proc test_reload { do_kill_p follow_child_p } {
|
|||||||
gdb_breakpoint "breakpt"
|
gdb_breakpoint "breakpt"
|
||||||
gdb_continue_to_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" \
|
gdb_test "info inferiors" \
|
||||||
[multi_line \
|
[multi_line \
|
||||||
" Num Description Executable.*" \
|
" Num${ws}Description${ws}Connection${ws}Executable${ws}" \
|
||||||
"${parent_prefix} 1 +${live_inf_ptn} \[^\r\n\]+" \
|
"${parent_prefix} 1${ws}${live_inf_ptn}${ws}${connection_re}${executable_re}" \
|
||||||
"${child_prefix} 2 +${live_inf_ptn} \[^\r\n\]+" ] \
|
"${child_prefix} 2${ws}${live_inf_ptn}${ws}${connection_re}${executable_re}" ] \
|
||||||
"Check inferiors at breakpoint"
|
"Check inferiors at breakpoint"
|
||||||
|
|
||||||
if { $do_kill_p } {
|
if { $do_kill_p } {
|
||||||
@ -107,9 +111,9 @@ proc test_reload { do_kill_p follow_child_p } {
|
|||||||
# Check the first inferior really did die.
|
# Check the first inferior really did die.
|
||||||
gdb_test "info inferiors" \
|
gdb_test "info inferiors" \
|
||||||
[multi_line \
|
[multi_line \
|
||||||
" Num Description Executable.*" \
|
" Num${ws}Description${ws}Connection${ws}Executable${ws}" \
|
||||||
"${parent_prefix} 1 +${parent_inf_after_kill_ptn} \[^\r\n\]+" \
|
"${parent_prefix} 1${ws}${parent_inf_after_kill_ptn}${ws}${connection_re}${executable_re}" \
|
||||||
"${child_prefix} 2 +${child_inf_after_kill_ptn} \[^\r\n\]+" ] \
|
"${child_prefix} 2${ws}${child_inf_after_kill_ptn}${ws}${connection_re}${executable_re}" ] \
|
||||||
"Check inferior was killed"
|
"Check inferior was killed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ proc do_test { detach_on_fork } {
|
|||||||
"no threads left"
|
"no threads left"
|
||||||
|
|
||||||
gdb_test "info inferiors" \
|
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"
|
"only inferior 1 left"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ proc do_test { cond_bp_target detach_on_fork displaced } {
|
|||||||
"no threads left"
|
"no threads left"
|
||||||
|
|
||||||
gdb_test "info inferiors" \
|
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"
|
"only inferior 1 left"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ proc use_collected_data { data_source } {
|
|||||||
# There is always a thread of an inferior, either a live one or
|
# There is always a thread of an inferior, either a live one or
|
||||||
# a faked one.
|
# a faked one.
|
||||||
gdb_test "info threads" "\\* ${decimal} (process|Thread) \[0-9\.\]+\[ \t\].*"
|
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}.*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user