* [RFA 01/08] multi-process support: struct inferior
@ 2008-09-12 15:38 Pedro Alves
2008-09-12 16:08 ` Eli Zaretskii
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Pedro Alves @ 2008-09-12 15:38 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 463 bytes --]
This patch adds a `struct inferior' object, and the code needed to
maintain an inferior list. The patch adds an inferior.c file (looks
like it was just waiting for this) -- you'll notice that the code
is very similar in principle to gdbthread.h/thread.c. That's not
a coincidence, this code was heavilly borrowed from there.
The object is still mostly empty in this patch. The following
patches will start moving a couple of globals into it.
--
Pedro Alves
[-- Attachment #2: 001-inferior_table.diff --]
[-- Type: text/x-diff, Size: 14577 bytes --]
gdb/
2008-09-12 Pedro Alves <pedro@codesourcery.com>
* inferior.h: Forward declare struct ui_out.
Forward declare struct private_inferior.
(struct inferior): New.
(init_inferior_list, add_inferior, add_inferior_silent)
(delete_inferior, delete_inferior_silent, detach_inferior)
(gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
(valid_inferior_id, find_inferior_pid): New functions.
(inferior_callback_func): New typedef.
(iterate_over_inferiors, print_inferior, have_inferiors)
(current_inferior): New functions.
* inferior.c: New file.
* Makefile.in (SFILES): Add inferior.c.
(COMMON_OBS): Add inferior.o.
gdb/doc/
2008-09-12 Pedro Alves <pedro@codesourcery.com>
* gdb.texinfo (Inferiors): New node.
(Listing Inferios): New section.
Document new "info inferiors" and "set/show inferior-events" commands.
---
gdb/Makefile.in | 6
gdb/doc/gdb.texinfo | 30 ++++
gdb/inferior.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/inferior.h | 85 +++++++++++++
4 files changed, 451 insertions(+), 2 deletions(-)
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2008-09-12 12:27:25.000000000 +0100
+++ src/gdb/Makefile.in 2008-09-12 12:27:27.000000000 +0100
@@ -655,7 +655,8 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
user-regs.c \
valarith.c valops.c valprint.c value.c varobj.c vec.c \
wrapper.c \
- xml-tdesc.c xml-support.c
+ xml-tdesc.c xml-support.c \
+ inferior.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
@@ -803,7 +804,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
tramp-frame.o \
solib.o solib-null.o \
prologue-value.o memory-map.o xml-support.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o
+ target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ inferior.o
TSOBS = inflow.o
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h 2008-09-12 12:27:25.000000000 +0100
+++ src/gdb/inferior.h 2008-09-12 12:43:11.000000000 +0100
@@ -29,6 +29,7 @@ struct ui_file;
struct type;
struct gdbarch;
struct regcache;
+struct ui_out;
/* For bpstat. */
#include "breakpoint.h"
@@ -397,4 +398,88 @@ extern int suppress_resume_observer;
#if !defined(START_INFERIOR_TRAPS_EXPECTED)
#define START_INFERIOR_TRAPS_EXPECTED 2
#endif
+
+struct private_inferior;
+
+struct inferior
+{
+ struct inferior *next;
+
+ int pid; /* Actual inferior id. Usually, a
+ process id. */
+ int num; /* Convenient handle (GDB inferior
+ id) */
+
+ /* Private data used by the target vector implementation. */
+ struct private_inferior *private;
+};
+
+/* Create an empty inferior list, or empty the existing one. */
+extern void init_inferior_list (void);
+
+/* Add an inferior to the inferior list, print a message that a new
+ inferior is found, and return the pointer to the new inferior.
+ Caller may use this pointer to initialize the private inferior
+ data. */
+extern struct inferior *add_inferior (int pid);
+
+/* Same as add_inferior, but don't print new inferior notifications to
+ the CLI. */
+extern struct inferior *add_inferior_silent (int pid);
+
+/* Delete an existing inferior list entry, due to inferior exit. */
+extern void delete_inferior (int pid);
+
+/* Same as delete_inferior, but don't print new inferior notifications
+ to the CLI. */
+extern void delete_inferior_silent (int pid);
+
+/* Delete an existing inferior list entry, due to inferior detaching. */
+extern void detach_inferior (int pid);
+
+/* Translate the integer inferior id (GDB's homegrown id, not the system's)
+ into a "pid" (which may be overloaded with extra inferior information). */
+extern int gdb_inferior_id_to_pid (int);
+
+/* Translate a target 'pid' into the integer inferior id (GDB's
+ homegrown id, not the system's). */
+extern int pid_to_gdb_inferior_id (int pid);
+
+/* Boolean test for an already-known pid. */
+extern int in_inferior_list (int pid);
+
+/* Boolean test for an already-known inferior id (GDB's homegrown id,
+ not the system's). */
+extern int valid_inferior_id (int gpid);
+
+/* Search function to lookup a inferior by target 'pid'. */
+extern struct inferior *find_inferior_pid (int pid);
+
+/* Inferior iterator function.
+
+ Calls a callback function once for each inferior, so long as the
+ callback function returns false. If the callback function returns
+ true, the iteration will end and the current inferior will be
+ returned. This can be useful for implementing a search for a
+ inferior with arbitrary attributes, or for applying some operation
+ to every inferior.
+
+ It is safe to delete the iterated inferior from the callback. */
+extern struct inferior *iterate_over_inferiors (int (*) (struct inferior *,
+ void *),
+ void *);
+
+/* Prints the list of inferiors and their details on UIOUT.
+
+ If REQUESTED_INFERIOR is not -1, it's the GDB id of the inferior
+ that should be printed. Otherwise, all inferiors are printed. */
+extern void print_inferior (struct ui_out *uiout, int requested_inferior);
+
+/* Returns true if the inferior list is not empty. */
+extern int have_inferiors (void);
+
+/* Return a pointer to the current inferior. It is an error to call
+ this if there is no current inferior. */
+extern struct inferior *current_inferior (void);
+
#endif /* !defined (INFERIOR_H) */
Index: src/gdb/inferior.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/inferior.c 2008-09-12 12:39:51.000000000 +0100
@@ -0,0 +1,332 @@
+/* Multi-process control for GDB, the GNU debugger.
+
+ Copyright (C) 2008 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 "inferior.h"
+#include "target.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "gdbthread.h"
+#include "ui-out.h"
+
+void _initialize_inferiors (void);
+
+static struct inferior *inferior_list = NULL;
+static int highest_inferior_num;
+
+/* Print notices on inferior events (attach, detach, etc.), set with
+ `set print inferior-events'. */
+static int print_inferior_events = 0;
+
+struct inferior*
+current_inferior (void)
+{
+ struct inferior *inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
+ gdb_assert (inf);
+ return inf;
+}
+
+static void
+free_inferior (struct inferior *inf)
+{
+ xfree (inf->private);
+ xfree (inf);
+}
+
+void
+init_inferior_list (void)
+{
+ struct inferior *inf, *infnext;
+
+ highest_inferior_num = 0;
+ if (!inferior_list)
+ return;
+
+ for (inf = inferior_list; inf; inf = infnext)
+ {
+ infnext = inf->next;
+ free_inferior (inf);
+ }
+
+ inferior_list = NULL;
+}
+
+struct inferior *
+add_inferior_silent (int pid)
+{
+ struct inferior *inf;
+
+ inf = xmalloc (sizeof (*inf));
+ memset (inf, 0, sizeof (*inf));
+ inf->pid = pid;
+
+ inf->num = ++highest_inferior_num;
+ inf->next = inferior_list;
+ inferior_list = inf;
+
+ return inf;
+}
+
+struct inferior *
+add_inferior (int pid)
+{
+ struct inferior *inf = add_inferior_silent (pid);
+
+ if (print_inferior_events)
+ printf_unfiltered (_("[New inferior %d]\n"), pid);
+
+ return inf;
+}
+
+struct delete_thread_of_inferior_arg
+{
+ int pid;
+ int silent;
+};
+
+static int
+delete_thread_of_inferior (struct thread_info *tp, void *data)
+{
+ struct delete_thread_of_inferior_arg *arg = data;
+
+ if (ptid_get_pid (tp->ptid) == arg->pid)
+ {
+ if (arg->silent)
+ delete_thread_silent (tp->ptid);
+ else
+ delete_thread (tp->ptid);
+ }
+
+ return 0;
+}
+
+/* If SILENT then be quiet -- don't announce a inferior death, or the
+ exit of its threads. */
+static void
+delete_inferior_1 (int pid, int silent)
+{
+ struct inferior *inf, *infprev;
+ struct delete_thread_of_inferior_arg arg = { pid, silent };
+
+ infprev = NULL;
+
+ for (inf = inferior_list; inf; infprev = inf, inf = inf->next)
+ if (inf->pid == pid)
+ break;
+
+ if (!inf)
+ return;
+
+ if (infprev)
+ infprev->next = inf->next;
+ else
+ inferior_list = inf->next;
+
+ free_inferior (inf);
+
+ arg.pid = pid;
+ arg.silent = silent;
+
+ iterate_over_threads (delete_thread_of_inferior, &arg);
+}
+
+void
+delete_inferior (int pid)
+{
+ delete_inferior_1 (pid, 0);
+
+ if (print_inferior_events)
+ printf_unfiltered (_("[Inferior %d exited]\n"), pid);
+}
+
+void
+delete_inferior_silent (int pid)
+{
+ delete_inferior_1 (pid, 1);
+}
+
+void
+detach_inferior (int pid)
+{
+ delete_inferior_1 (pid, 1);
+
+ if (print_inferior_events)
+ printf_unfiltered (_("[Inferior %d detached]\n"), pid);
+}
+
+static struct inferior *
+find_inferior_id (int num)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->num == num)
+ return inf;
+
+ return NULL;
+}
+
+struct inferior *
+find_inferior_pid (int pid)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->pid == pid)
+ return inf;
+
+ return NULL;
+}
+
+struct inferior *
+iterate_over_inferiors (int (*callback) (struct inferior *, void *),
+ void *data)
+{
+ struct inferior *inf, *infnext;
+
+ for (inf = inferior_list; inf; inf = infnext)
+ {
+ infnext = inf->next;
+ if ((*callback) (inf, data))
+ return inf;
+ }
+
+ return NULL;
+}
+
+int
+valid_gdb_inferior_id (int num)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->num == num)
+ return 1;
+
+ return 0;
+}
+
+int
+pid_to_gdb_inferior_id (int pid)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->pid == pid)
+ return inf->num;
+
+ return 0;
+}
+
+int
+gdb_inferior_id_to_pid (int num)
+{
+ struct inferior *inferior = find_inferior_id (num);
+ if (inferior)
+ return inferior->pid;
+ else
+ return -1;
+}
+
+int
+in_inferior_list (int pid)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->pid == pid)
+ return 1;
+
+ return 0;
+}
+
+int
+have_inferiors (void)
+{
+ return inferior_list != NULL;
+}
+
+/* Prints the list of inferiors and their details on UIOUT. This is a
+ version of 'info_inferior_command' suitable for use from MI.
+
+ If REQUESTED_INFERIOR is not -1, it's the GDB id of the inferior that
+ should be printed. Otherwise, all inferiors are printed. */
+void
+print_inferior (struct ui_out *uiout, int requested_inferior)
+{
+ struct inferior *inf;
+ struct cleanup *old_chain;
+
+ old_chain = make_cleanup_ui_out_list_begin_end (uiout, "inferiors");
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ {
+ struct cleanup *chain2;
+
+ if (requested_inferior != -1 && inf->num != requested_inferior)
+ continue;
+
+ chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+ if (inf->pid == ptid_get_pid (inferior_ptid))
+ ui_out_text (uiout, "* ");
+ else
+ ui_out_text (uiout, " ");
+
+ ui_out_field_int (uiout, "id", inf->num);
+ ui_out_text (uiout, " ");
+ ui_out_field_int (uiout, "target-id", inf->pid);
+
+ ui_out_text (uiout, "\n");
+ do_cleanups (chain2);
+ }
+
+ do_cleanups (old_chain);
+}
+
+/* Print information about currently known inferiors. */
+
+static void
+info_inferiors_command (char *arg, int from_tty)
+{
+ print_inferior (uiout, -1);
+}
+
+/* Print notices when new inferiors are created and die. */
+static void
+show_print_inferior_events (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Printing of inferior events is %s.\n"), value);
+}
+
+void
+_initialize_inferiors (void)
+{
+ add_info ("inferiors", info_inferiors_command,
+ _("IDs of currently known inferiors."));
+
+ add_setshow_boolean_cmd ("inferior-events", no_class,
+ &print_inferior_events, _("\
+Set printing of inferior events (e.g., inferior start and exit)."), _("\
+Show printing of inferior events (e.g., inferior start and exit)."), NULL,
+ NULL,
+ show_print_inferior_events,
+ &setprintlist, &showprintlist);
+}
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2008-09-12 12:27:25.000000000 +0100
+++ src/gdb/doc/gdb.texinfo 2008-09-12 12:27:27.000000000 +0100
@@ -2750,6 +2750,36 @@ You can use the @code{catch} command to
a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set
Catchpoints, ,Setting Catchpoints}.
+@node Inferiors
+@section Listing Inferiors
+
+@value{GDBN} keeps track of the inferiors under control, be them
+either running processes, core files, or remote targets without a
+notion of processes, but which nonetheless have execution, and allows
+the user to query and be notified about them uniformally, using the
+commands below.
+
+@table @code
+@kindex info inferiors
+@item info inferiors
+Print a list of all inferiors under the control of @value{GDBN}.
+
+@kindex set print inferior-events
+@cindex print messages on inferior start and exit
+@item set print inferior-events
+@itemx set print inferior-events on
+@itemx set print inferior-events off
+The @code{set print inferior-events} command allows you to enable or
+disable printing of messages when @value{GDBN} notices that new
+inferiors have started or that inferiors have exited or have been
+detached. By default, these messages will not be printed.
+
+@kindex show print inferior-events
+@item show print inferior-events
+Show whether messages will be printed when @value{GDBN} detects that
+inferiors have started, exited or have been detached.
+@end table
+
@node Checkpoint/Restart
@section Setting a @emph{Bookmark} to Return to Later
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-12 15:38 [RFA 01/08] multi-process support: struct inferior Pedro Alves
2008-09-12 16:08 ` Eli Zaretskii
@ 2008-09-12 16:08 ` Eli Zaretskii
2008-09-17 0:33 ` [RFA 01/08] multi-process support: struct inferior (alternate manual content) Stan Shebs
2008-09-18 22:46 ` [RFA 01/08] multi-process support: struct inferior Daniel Jacobowitz
3 siblings, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2008-09-12 16:08 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
> From: Pedro Alves <pedro@codesourcery.com>
> Date: Fri, 12 Sep 2008 16:37:34 +0100
>
> +@node Inferiors
> +@section Listing Inferiors
Some index entry should be here.
Also, I'm not sure this should be a top-level @section (but if it is,
I believe you will have to add it to the top-level menu as well). How
about making it a subsection of "Running"?
> +@value{GDBN} keeps track of the inferiors under control, be them
> +either running processes, core files, or remote targets without a
> +notion of processes, but which nonetheless have execution, and allows
> +the user to query and be notified about them uniformally, using the
> +commands below.
This text falls short of explaining why these features are useful.
Can we add something to explain this better?
> +The @code{set print inferior-events} command allows you to enable or
> +disable printing of messages when @value{GDBN} notices that new
> +inferiors have started or that inferiors have exited or have been
> +detached. By default, these messages will not be printed.
If the default is off, then perhaps we should tell when would the user
want them on. But maybe if you add explanation I asked for above,
they will clarify this as well.
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-12 15:38 [RFA 01/08] multi-process support: struct inferior Pedro Alves
@ 2008-09-12 16:08 ` Eli Zaretskii
2008-09-12 17:21 ` Pedro Alves
2008-09-12 16:08 ` Eli Zaretskii
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Eli Zaretskii @ 2008-09-12 16:08 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
> From: Pedro Alves <pedro@codesourcery.com>
> Date: Fri, 12 Sep 2008 16:37:34 +0100
>
> +@node Inferiors
> +@section Listing Inferiors
Some index entry should be here.
Also, I'm not sure this should be a top-level @section (but if it is,
I believe you will have to add it to the top-level menu as well). How
about making it a subsection of "Running"?
> +@value{GDBN} keeps track of the inferiors under control, be them
> +either running processes, core files, or remote targets without a
> +notion of processes, but which nonetheless have execution, and allows
> +the user to query and be notified about them uniformally, using the
> +commands below.
This text falls short of explaining why these features are useful.
Can we add something to explain this better?
> +The @code{set print inferior-events} command allows you to enable or
> +disable printing of messages when @value{GDBN} notices that new
> +inferiors have started or that inferiors have exited or have been
> +detached. By default, these messages will not be printed.
If the default is off, then perhaps we should tell when would the user
want them on. But maybe if you add explanation I asked for above,
they will clarify this as well.
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-12 16:08 ` Eli Zaretskii
@ 2008-09-12 17:21 ` Pedro Alves
2008-09-12 20:00 ` Eli Zaretskii
0 siblings, 1 reply; 10+ messages in thread
From: Pedro Alves @ 2008-09-12 17:21 UTC (permalink / raw)
To: gdb-patches, Eli Zaretskii
On Friday 12 September 2008 17:08:16, Eli Zaretskii wrote:
> > From: Pedro Alves <pedro@codesourcery.com>
> > Date: Fri, 12 Sep 2008 16:37:34 +0100
> >
> > +@node Inferiors
> > +@section Listing Inferiors
>
> Some index entry should be here.
>
> Also, I'm not sure this should be a top-level @section (but if it is,
> I believe you will have to add it to the top-level menu as well). How
> about making it a subsection of "Running"?
Fine with me. I was just putting it close to the current docs for
multi-fork/multi-process support. In fact, I'm just trying to place
the documentation of the new commands somewhere. I'm quite sure that
Stan will end up expanding/rewriting this much with the docs for:
http://sourceware.org/ml/gdb/2008-08/msg00169.html
> > +@value{GDBN} keeps track of the inferiors under control, be them
> > +either running processes, core files, or remote targets without a
> > +notion of processes, but which nonetheless have execution, and allows
> > +the user to query and be notified about them uniformally, using the
> > +commands below.
>
> This text falls short of explaining why these features are useful.
> Can we add something to explain this better?
Hmmm, when you're attached to multiple inferiors, you naturally want to
be able to get a list of those. I didn't put an example up, as
currently it is boring:
(gdb) info inferiors
* 2 16837
1 16836
This will grow in documentation and usefulness as later patches,
documentation and multi-exec support is submitted.
In the mean time, it'd be helpful to know what sort of something
you'd like explained better, as obviously, I thought that
the description under the commands was enough. But that's surelly
because I've been staring at these issues for too long. :-)
> > +The @code{set print inferior-events} command allows you to enable or
> > +disable printing of messages when @value{GDBN} notices that new
> > +inferiors have started or that inferiors have exited or have been
> > +detached. By default, these messages will not be printed.
>
> If the default is off, then perhaps we should tell when would the user
> want them on. But maybe if you add explanation I asked for above,
> they will clarify this as well.
Hmmm, since the description of the command explain what it does,
I figure the user will want it, when he wants what is described
above. This is about the same level of detail as
"set print thread-events". I disabled it by default, because it's
what GDB does currently.
The below is against a multi-process gdbserver:
(gdb) b main
Breakpoint 1 at 0x80484d5: file threads.c, line 35.
(gdb) tar extended-remote :9999
Remote debugging using :9999
(gdb) r
Starting program: /home/pedro/gdb/tests/threads32
[New inferior 16983]
^^^^^^^^^^^^^^^^^^^^
Breakpoint 1, main () at threads.c:35
35 long i = 0;
(gdb)
As we extend the multi-process support, this
messages will get a bit smarter (the target may decide to use
some other text for the message, like we do with
thread messages), but we're not there yet.
--
Pedro Alves
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-12 17:21 ` Pedro Alves
@ 2008-09-12 20:00 ` Eli Zaretskii
2008-09-16 22:05 ` Stan Shebs
0 siblings, 1 reply; 10+ messages in thread
From: Eli Zaretskii @ 2008-09-12 20:00 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
> From: Pedro Alves <pedro@codesourcery.com>
> Date: Fri, 12 Sep 2008 18:20:43 +0100
>
> > > +@value{GDBN} keeps track of the inferiors under control, be them
> > > +either running processes, core files, or remote targets without a
> > > +notion of processes, but which nonetheless have execution, and allows
> > > +the user to query and be notified about them uniformally, using the
> > > +commands below.
> >
> > This text falls short of explaining why these features are useful.
> > Can we add something to explain this better?
>
> Hmmm, when you're attached to multiple inferiors, you naturally want to
> be able to get a list of those.
Ah, but no one said anything about attaching to multiple inferiors
yet. This text is written as if debugging multiple inferiors was
discussed in the manual everywhere since page 1, but it wasn't.
> This will grow in documentation and usefulness as later patches,
> documentation and multi-exec support is submitted.
Right, but we still need some introductory text to break the news on
the reader that GDB can debug several inferiors at once. A couple of
use cases where this would be useful will not do any harm, either.
IOW, people who debug programs usually do that one program at a time,
so we cannot seamlessly start talking about commands that support
multi-process paradigm without introducing the reader to the feature.
> (gdb) r
> Starting program: /home/pedro/gdb/tests/threads32
> [New inferior 16983]
> ^^^^^^^^^^^^^^^^^^^^
Should we perhaps automatically set print inferior-events on when a
second inferior is started?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-12 20:00 ` Eli Zaretskii
@ 2008-09-16 22:05 ` Stan Shebs
0 siblings, 0 replies; 10+ messages in thread
From: Stan Shebs @ 2008-09-16 22:05 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Pedro Alves, gdb-patches
Eli Zaretskii wrote:
> [...] we still need some introductory text to break the news on
> the reader that GDB can debug several inferiors at once. A couple of
> use cases where this would be useful will not do any harm, either.
>
> IOW, people who debug programs usually do that one program at a time,
> so we cannot seamlessly start talking about commands that support
> multi-process paradigm without introducing the reader to the feature.
>
At the moment, I'm working with a section "Debugging Multiple Programs"
just in front of the "Running" / "Threads" section, plus there are bits
about multiple executables in the "Invocation" chapter. I don't think we
want to push it up too much further, because 99% of GDB users don't care
about multiple whatevers, and we don't want to get them mired down in
this new level of complexity. A pre-multi-executable version of this
section could maybe just introduce the concept of inferiors and not say
much more except that multiple inferiors can be created via certain
targets, such as the remote protocol. We could title it "Inferiors" in
the meantime, and yes, it will seem a little odd to have both that and a
"Processes" section soon after, but as of yet I don't have a good feel
for how to best to merge the two, and given the coming upheavals, I'd
just as soon wait until the multi-exec bits come in.
Stan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior (alternate manual content)
2008-09-12 15:38 [RFA 01/08] multi-process support: struct inferior Pedro Alves
2008-09-12 16:08 ` Eli Zaretskii
2008-09-12 16:08 ` Eli Zaretskii
@ 2008-09-17 0:33 ` Stan Shebs
2008-09-17 3:17 ` Eli Zaretskii
2008-09-18 22:46 ` [RFA 01/08] multi-process support: struct inferior Daniel Jacobowitz
3 siblings, 1 reply; 10+ messages in thread
From: Stan Shebs @ 2008-09-17 0:33 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 510 bytes --]
Here is an alternate phrasing for GDB's new inferior objects,
wordsmithed so that it (mostly) makes sense with just Pedro's patches,
and also so that it can be easily expanded into the full multi-exec
section in the near future. To repeat from my last comment, I don't
think we need to be really polished just yet, the single-exec +
multi-inferior case is just a transitional stage of limited interest.
Stan
2008-09-16 Stan Shebs <stan@codesourcery.com>
* gdb.texinfo (Inferiors): New section.
[-- Attachment #2: manual-inf-patch-1 --]
[-- Type: text/plain, Size: 3045 bytes --]
Index: gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.521
diff -p -r1.521 gdb.texinfo
*** gdb.texinfo 3 Sep 2008 23:54:19 -0000 1.521
--- gdb.texinfo 17 Sep 2008 00:25:23 -0000
*************** kill a child process.
*** 1785,1790 ****
--- 1785,1791 ----
* Attach:: Debugging an already-running process
* Kill Process:: Killing the child process
+ * Inferiors:: Debugging multiple inferiors
* Threads:: Debugging programs with multiple threads
* Processes:: Debugging programs with multiple processes
* Checkpoint/Restart:: Setting a @emph{bookmark} to return to later
*************** next type @code{run}, @value{GDBN} notic
*** 2354,2359 ****
--- 2355,2406 ----
reads the symbol table again (while trying to preserve your current
breakpoint settings).
+ @node Inferiors
+ @section Debugging Multiple Inferiors
+
+ Some @value{GDBN} targets are able to run multiple processes created
+ from a single executable. This can happen, for instance, with an
+ embedded system reporting back several processes via the remote
+ protocol.
+
+ @cindex inferior
+ @value{GDBN} represents the state of each program execution with an
+ object called an @dfn{inferior}. An inferior typically corresponds to a
+ process, but is more general and applies also to targets that do not
+ have processes. Inferiors may be created before a process runs, and
+ may (in future) be retained after a process exits. Each run of an
+ executable creates a new inferior, as does each attachment to an
+ existing process. Inferiors have unique identifiers that are different
+ from process ids, and may optionally be named as well. Usually each
+ inferior will also have its own distinct address space, although some
+ embedded targets may have several inferiors running in different parts
+ of a single space.
+
+ Each inferior may in turn have multiple threads running in it.
+
+ To find out what inferiors exist at any moment, use @code{info inferiors}:
+
+ @table @code
+ @kindex info inferiors
+ @item info inferiors
+ Print a list of all inferiors currently being managed by @value{GDBN}.
+
+ @kindex set print inferior-events
+ @cindex print messages on inferior start and exit
+ @item set print inferior-events
+ @itemx set print inferior-events on
+ @itemx set print inferior-events off
+ The @code{set print inferior-events} command allows you to enable or
+ disable printing of messages when @value{GDBN} notices that new
+ inferiors have started or that inferiors have exited or have been
+ detached. By default, these messages will not be printed.
+
+ @kindex show print inferior-events
+ @item show print inferior-events
+ Show whether messages will be printed when @value{GDBN} detects that
+ inferiors have started, exited or have been detached.
+ @end table
+
@node Threads
@section Debugging Programs with Multiple Threads
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior (alternate manual content)
2008-09-17 0:33 ` [RFA 01/08] multi-process support: struct inferior (alternate manual content) Stan Shebs
@ 2008-09-17 3:17 ` Eli Zaretskii
0 siblings, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2008-09-17 3:17 UTC (permalink / raw)
To: Stan Shebs; +Cc: pedro, gdb-patches
> Date: Tue, 16 Sep 2008 17:32:30 -0700
> From: Stan Shebs <stan@codesourcery.com>
> CC: gdb-patches@sourceware.org
>
> Here is an alternate phrasing for GDB's new inferior objects,
> wordsmithed so that it (mostly) makes sense with just Pedro's patches,
> and also so that it can be easily expanded into the full multi-exec
> section in the near future. To repeat from my last comment, I don't
> think we need to be really polished just yet, the single-exec +
> multi-inferior case is just a transitional stage of limited interest.
>
> Stan
>
> 2008-09-16 Stan Shebs <stan@codesourcery.com>
>
> * gdb.texinfo (Inferiors): New section.
Thanks, this is okay.
> + An inferior typically corresponds to a
> + process, but is more general and applies also to targets that do not
> + have processes.
An example of an inferior that is not a process will help here.
Also, please make sure there are 2 spaces between each 2 sentences.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-12 15:38 [RFA 01/08] multi-process support: struct inferior Pedro Alves
` (2 preceding siblings ...)
2008-09-17 0:33 ` [RFA 01/08] multi-process support: struct inferior (alternate manual content) Stan Shebs
@ 2008-09-18 22:46 ` Daniel Jacobowitz
2008-09-22 15:35 ` Pedro Alves
3 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2008-09-18 22:46 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On Fri, Sep 12, 2008 at 04:37:34PM +0100, Pedro Alves wrote:
> gdb/
> 2008-09-12 Pedro Alves <pedro@codesourcery.com>
>
> * inferior.h: Forward declare struct ui_out.
> Forward declare struct private_inferior.
> (struct inferior): New.
> (init_inferior_list, add_inferior, add_inferior_silent)
> (delete_inferior, delete_inferior_silent, detach_inferior)
> (gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
> (valid_inferior_id, find_inferior_pid): New functions.
> (inferior_callback_func): New typedef.
> (iterate_over_inferiors, print_inferior, have_inferiors)
> (current_inferior): New functions.
> * inferior.c: New file.
>
> * Makefile.in (SFILES): Add inferior.c.
> (COMMON_OBS): Add inferior.o.
This code, with Stan's doc patch and Eli's comments on it, is OK to
commit.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA 01/08] multi-process support: struct inferior
2008-09-18 22:46 ` [RFA 01/08] multi-process support: struct inferior Daniel Jacobowitz
@ 2008-09-22 15:35 ` Pedro Alves
0 siblings, 0 replies; 10+ messages in thread
From: Pedro Alves @ 2008-09-22 15:35 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1103 bytes --]
On Thursday 18 September 2008 23:45:55, Daniel Jacobowitz wrote:
> On Fri, Sep 12, 2008 at 04:37:34PM +0100, Pedro Alves wrote:
> > gdb/
> > 2008-09-12 Pedro Alves <pedro@codesourcery.com>
> >
> > * inferior.h: Forward declare struct ui_out.
> > Forward declare struct private_inferior.
> > (struct inferior): New.
> > (init_inferior_list, add_inferior, add_inferior_silent)
> > (delete_inferior, delete_inferior_silent, detach_inferior)
> > (gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
> > (valid_inferior_id, find_inferior_pid): New functions.
> > (inferior_callback_func): New typedef.
> > (iterate_over_inferiors, print_inferior, have_inferiors)
> > (current_inferior): New functions.
> > * inferior.c: New file.
> >
> > * Makefile.in (SFILES): Add inferior.c.
> > (COMMON_OBS): Add inferior.o.
>
> This code, with Stan's doc patch and Eli's comments on it, is OK to
> commit.
Thanks. I've checked it in. I took the liberty of adding a comment
describing struct inferior, similar to what's being put in the manual.
Here's what I checked in.
--
Pedro Alves
[-- Attachment #2: 001-inferior_table.diff --]
[-- Type: text/x-diff, Size: 16421 bytes --]
gdb/
2008-09-22 Pedro Alves <pedro@codesourcery.com>
* inferior.h: Forward declare struct ui_out.
Forward declare struct private_inferior.
(struct inferior): New.
(init_inferior_list, add_inferior, add_inferior_silent)
(delete_inferior, delete_inferior_silent, detach_inferior)
(gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
(valid_inferior_id, find_inferior_pid): New functions.
(inferior_callback_func): New typedef.
(iterate_over_inferiors, print_inferior, have_inferiors)
(current_inferior): New functions.
* inferior.c: New file.
* Makefile.in (SFILES): Add inferior.c.
(COMMON_OBS): Add inferior.o.
gdb/doc/
2008-09-22 Stan Shebs <stan@codesourcery.com>
* gdb.texinfo (Inferiors): New section.
---
gdb/Makefile.in | 6
gdb/doc/gdb.texinfo | 47 +++++++
gdb/inferior.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/inferior.h | 98 +++++++++++++++
4 files changed, 481 insertions(+), 2 deletions(-)
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2008-09-19 14:02:31.000000000 +0100
+++ src/gdb/Makefile.in 2008-09-19 14:03:12.000000000 +0100
@@ -655,7 +655,8 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
user-regs.c \
valarith.c valops.c valprint.c value.c varobj.c vec.c \
wrapper.c \
- xml-tdesc.c xml-support.c
+ xml-tdesc.c xml-support.c \
+ inferior.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
@@ -803,7 +804,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
tramp-frame.o \
solib.o solib-null.o \
prologue-value.o memory-map.o xml-support.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o
+ target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ inferior.o
TSOBS = inflow.o
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h 2008-09-19 13:57:04.000000000 +0100
+++ src/gdb/inferior.h 2008-09-19 14:32:35.000000000 +0100
@@ -29,6 +29,7 @@ struct ui_file;
struct type;
struct gdbarch;
struct regcache;
+struct ui_out;
/* For bpstat. */
#include "breakpoint.h"
@@ -397,4 +398,101 @@ extern int suppress_resume_observer;
#if !defined(START_INFERIOR_TRAPS_EXPECTED)
#define START_INFERIOR_TRAPS_EXPECTED 2
#endif
+
+struct private_inferior;
+
+/* GDB represents the state of each program execution with an object
+ called an inferior. An inferior typically corresponds to a process
+ but is more general and applies also to targets that do not have a
+ notion of processes. Each run of an executable creates a new
+ inferior, as does each attachment to an existing process.
+ Inferiors have unique internal identifiers that are different from
+ target process ids. Each inferior may in turn have multiple
+ threads running in it. */
+
+struct inferior
+{
+ /* Pointer to next inferior in singly-linked list of inferiors. */
+ struct inferior *next;
+
+ /* Convenient handle (GDB inferior id). Unique across all
+ inferiors. */
+ int num;
+
+ /* Actual target inferior id, usually, a process id. This matches
+ the ptid_t.pid member of threads of this inferior. */
+ int pid;
+
+ /* Private data used by the target vector implementation. */
+ struct private_inferior *private;
+};
+
+/* Create an empty inferior list, or empty the existing one. */
+extern void init_inferior_list (void);
+
+/* Add an inferior to the inferior list, print a message that a new
+ inferior is found, and return the pointer to the new inferior.
+ Caller may use this pointer to initialize the private inferior
+ data. */
+extern struct inferior *add_inferior (int pid);
+
+/* Same as add_inferior, but don't print new inferior notifications to
+ the CLI. */
+extern struct inferior *add_inferior_silent (int pid);
+
+/* Delete an existing inferior list entry, due to inferior exit. */
+extern void delete_inferior (int pid);
+
+/* Same as delete_inferior, but don't print new inferior notifications
+ to the CLI. */
+extern void delete_inferior_silent (int pid);
+
+/* Delete an existing inferior list entry, due to inferior detaching. */
+extern void detach_inferior (int pid);
+
+/* Translate the integer inferior id (GDB's homegrown id, not the system's)
+ into a "pid" (which may be overloaded with extra inferior information). */
+extern int gdb_inferior_id_to_pid (int);
+
+/* Translate a target 'pid' into the integer inferior id (GDB's
+ homegrown id, not the system's). */
+extern int pid_to_gdb_inferior_id (int pid);
+
+/* Boolean test for an already-known pid. */
+extern int in_inferior_list (int pid);
+
+/* Boolean test for an already-known inferior id (GDB's homegrown id,
+ not the system's). */
+extern int valid_inferior_id (int num);
+
+/* Search function to lookup a inferior by target 'pid'. */
+extern struct inferior *find_inferior_pid (int pid);
+
+/* Inferior iterator function.
+
+ Calls a callback function once for each inferior, so long as the
+ callback function returns false. If the callback function returns
+ true, the iteration will end and the current inferior will be
+ returned. This can be useful for implementing a search for a
+ inferior with arbitrary attributes, or for applying some operation
+ to every inferior.
+
+ It is safe to delete the iterated inferior from the callback. */
+extern struct inferior *iterate_over_inferiors (int (*) (struct inferior *,
+ void *),
+ void *);
+
+/* Prints the list of inferiors and their details on UIOUT.
+
+ If REQUESTED_INFERIOR is not -1, it's the GDB id of the inferior
+ that should be printed. Otherwise, all inferiors are printed. */
+extern void print_inferior (struct ui_out *uiout, int requested_inferior);
+
+/* Returns true if the inferior list is not empty. */
+extern int have_inferiors (void);
+
+/* Return a pointer to the current inferior. It is an error to call
+ this if there is no current inferior. */
+extern struct inferior *current_inferior (void);
+
#endif /* !defined (INFERIOR_H) */
Index: src/gdb/inferior.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/inferior.c 2008-09-19 14:03:12.000000000 +0100
@@ -0,0 +1,332 @@
+/* Multi-process control for GDB, the GNU debugger.
+
+ Copyright (C) 2008 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 "inferior.h"
+#include "target.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "gdbthread.h"
+#include "ui-out.h"
+
+void _initialize_inferiors (void);
+
+static struct inferior *inferior_list = NULL;
+static int highest_inferior_num;
+
+/* Print notices on inferior events (attach, detach, etc.), set with
+ `set print inferior-events'. */
+static int print_inferior_events = 0;
+
+struct inferior*
+current_inferior (void)
+{
+ struct inferior *inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
+ gdb_assert (inf);
+ return inf;
+}
+
+static void
+free_inferior (struct inferior *inf)
+{
+ xfree (inf->private);
+ xfree (inf);
+}
+
+void
+init_inferior_list (void)
+{
+ struct inferior *inf, *infnext;
+
+ highest_inferior_num = 0;
+ if (!inferior_list)
+ return;
+
+ for (inf = inferior_list; inf; inf = infnext)
+ {
+ infnext = inf->next;
+ free_inferior (inf);
+ }
+
+ inferior_list = NULL;
+}
+
+struct inferior *
+add_inferior_silent (int pid)
+{
+ struct inferior *inf;
+
+ inf = xmalloc (sizeof (*inf));
+ memset (inf, 0, sizeof (*inf));
+ inf->pid = pid;
+
+ inf->num = ++highest_inferior_num;
+ inf->next = inferior_list;
+ inferior_list = inf;
+
+ return inf;
+}
+
+struct inferior *
+add_inferior (int pid)
+{
+ struct inferior *inf = add_inferior_silent (pid);
+
+ if (print_inferior_events)
+ printf_unfiltered (_("[New inferior %d]\n"), pid);
+
+ return inf;
+}
+
+struct delete_thread_of_inferior_arg
+{
+ int pid;
+ int silent;
+};
+
+static int
+delete_thread_of_inferior (struct thread_info *tp, void *data)
+{
+ struct delete_thread_of_inferior_arg *arg = data;
+
+ if (ptid_get_pid (tp->ptid) == arg->pid)
+ {
+ if (arg->silent)
+ delete_thread_silent (tp->ptid);
+ else
+ delete_thread (tp->ptid);
+ }
+
+ return 0;
+}
+
+/* If SILENT then be quiet -- don't announce a inferior death, or the
+ exit of its threads. */
+static void
+delete_inferior_1 (int pid, int silent)
+{
+ struct inferior *inf, *infprev;
+ struct delete_thread_of_inferior_arg arg = { pid, silent };
+
+ infprev = NULL;
+
+ for (inf = inferior_list; inf; infprev = inf, inf = inf->next)
+ if (inf->pid == pid)
+ break;
+
+ if (!inf)
+ return;
+
+ if (infprev)
+ infprev->next = inf->next;
+ else
+ inferior_list = inf->next;
+
+ free_inferior (inf);
+
+ arg.pid = pid;
+ arg.silent = silent;
+
+ iterate_over_threads (delete_thread_of_inferior, &arg);
+}
+
+void
+delete_inferior (int pid)
+{
+ delete_inferior_1 (pid, 0);
+
+ if (print_inferior_events)
+ printf_unfiltered (_("[Inferior %d exited]\n"), pid);
+}
+
+void
+delete_inferior_silent (int pid)
+{
+ delete_inferior_1 (pid, 1);
+}
+
+void
+detach_inferior (int pid)
+{
+ delete_inferior_1 (pid, 1);
+
+ if (print_inferior_events)
+ printf_unfiltered (_("[Inferior %d detached]\n"), pid);
+}
+
+static struct inferior *
+find_inferior_id (int num)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->num == num)
+ return inf;
+
+ return NULL;
+}
+
+struct inferior *
+find_inferior_pid (int pid)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->pid == pid)
+ return inf;
+
+ return NULL;
+}
+
+struct inferior *
+iterate_over_inferiors (int (*callback) (struct inferior *, void *),
+ void *data)
+{
+ struct inferior *inf, *infnext;
+
+ for (inf = inferior_list; inf; inf = infnext)
+ {
+ infnext = inf->next;
+ if ((*callback) (inf, data))
+ return inf;
+ }
+
+ return NULL;
+}
+
+int
+valid_gdb_inferior_id (int num)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->num == num)
+ return 1;
+
+ return 0;
+}
+
+int
+pid_to_gdb_inferior_id (int pid)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->pid == pid)
+ return inf->num;
+
+ return 0;
+}
+
+int
+gdb_inferior_id_to_pid (int num)
+{
+ struct inferior *inferior = find_inferior_id (num);
+ if (inferior)
+ return inferior->pid;
+ else
+ return -1;
+}
+
+int
+in_inferior_list (int pid)
+{
+ struct inferior *inf;
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ if (inf->pid == pid)
+ return 1;
+
+ return 0;
+}
+
+int
+have_inferiors (void)
+{
+ return inferior_list != NULL;
+}
+
+/* Prints the list of inferiors and their details on UIOUT. This is a
+ version of 'info_inferior_command' suitable for use from MI.
+
+ If REQUESTED_INFERIOR is not -1, it's the GDB id of the inferior that
+ should be printed. Otherwise, all inferiors are printed. */
+void
+print_inferior (struct ui_out *uiout, int requested_inferior)
+{
+ struct inferior *inf;
+ struct cleanup *old_chain;
+
+ old_chain = make_cleanup_ui_out_list_begin_end (uiout, "inferiors");
+
+ for (inf = inferior_list; inf; inf = inf->next)
+ {
+ struct cleanup *chain2;
+
+ if (requested_inferior != -1 && inf->num != requested_inferior)
+ continue;
+
+ chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+ if (inf->pid == ptid_get_pid (inferior_ptid))
+ ui_out_text (uiout, "* ");
+ else
+ ui_out_text (uiout, " ");
+
+ ui_out_field_int (uiout, "id", inf->num);
+ ui_out_text (uiout, " ");
+ ui_out_field_int (uiout, "target-id", inf->pid);
+
+ ui_out_text (uiout, "\n");
+ do_cleanups (chain2);
+ }
+
+ do_cleanups (old_chain);
+}
+
+/* Print information about currently known inferiors. */
+
+static void
+info_inferiors_command (char *arg, int from_tty)
+{
+ print_inferior (uiout, -1);
+}
+
+/* Print notices when new inferiors are created and die. */
+static void
+show_print_inferior_events (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Printing of inferior events is %s.\n"), value);
+}
+
+void
+_initialize_inferiors (void)
+{
+ add_info ("inferiors", info_inferiors_command,
+ _("IDs of currently known inferiors."));
+
+ add_setshow_boolean_cmd ("inferior-events", no_class,
+ &print_inferior_events, _("\
+Set printing of inferior events (e.g., inferior start and exit)."), _("\
+Show printing of inferior events (e.g., inferior start and exit)."), NULL,
+ NULL,
+ show_print_inferior_events,
+ &setprintlist, &showprintlist);
+}
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2008-09-19 14:03:31.000000000 +0100
+++ src/gdb/doc/gdb.texinfo 2008-09-19 14:07:27.000000000 +0100
@@ -1785,6 +1785,7 @@ kill a child process.
* Attach:: Debugging an already-running process
* Kill Process:: Killing the child process
+* Inferiors:: Debugging multiple inferiors
* Threads:: Debugging programs with multiple threads
* Processes:: Debugging programs with multiple processes
* Checkpoint/Restart:: Setting a @emph{bookmark} to return to later
@@ -2354,6 +2355,52 @@ next type @code{run}, @value{GDBN} notic
reads the symbol table again (while trying to preserve your current
breakpoint settings).
+@node Inferiors
+@section Debugging Multiple Inferiors
+
+Some @value{GDBN} targets are able to run multiple processes created
+from a single executable. This can happen, for instance, with an
+embedded system reporting back several processes via the remote
+protocol.
+
+@cindex inferior
+@value{GDBN} represents the state of each program execution with an
+object called an @dfn{inferior}. An inferior typically corresponds to
+a process, but is more general and applies also to targets that do not
+have processes. Inferiors may be created before a process runs, and
+may (in future) be retained after a process exits. Each run of an
+executable creates a new inferior, as does each attachment to an
+existing process. Inferiors have unique identifiers that are
+different from process ids, and may optionally be named as well.
+Usually each inferior will also have its own distinct address space,
+although some embedded targets may have several inferiors running in
+different parts of a single space.
+
+Each inferior may in turn have multiple threads running in it.
+
+To find out what inferiors exist at any moment, use @code{info inferiors}:
+
+@table @code
+@kindex info inferiors
+@item info inferiors
+Print a list of all inferiors currently being managed by @value{GDBN}.
+
+@kindex set print inferior-events
+@cindex print messages on inferior start and exit
+@item set print inferior-events
+@itemx set print inferior-events on
+@itemx set print inferior-events off
+The @code{set print inferior-events} command allows you to enable or
+disable printing of messages when @value{GDBN} notices that new
+inferiors have started or that inferiors have exited or have been
+detached. By default, these messages will not be printed.
+
+@kindex show print inferior-events
+@item show print inferior-events
+Show whether messages will be printed when @value{GDBN} detects that
+inferiors have started, exited or have been detached.
+@end table
+
@node Threads
@section Debugging Programs with Multiple Threads
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-09-22 15:35 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-12 15:38 [RFA 01/08] multi-process support: struct inferior Pedro Alves
2008-09-12 16:08 ` Eli Zaretskii
2008-09-12 17:21 ` Pedro Alves
2008-09-12 20:00 ` Eli Zaretskii
2008-09-16 22:05 ` Stan Shebs
2008-09-12 16:08 ` Eli Zaretskii
2008-09-17 0:33 ` [RFA 01/08] multi-process support: struct inferior (alternate manual content) Stan Shebs
2008-09-17 3:17 ` Eli Zaretskii
2008-09-18 22:46 ` [RFA 01/08] multi-process support: struct inferior Daniel Jacobowitz
2008-09-22 15:35 ` Pedro Alves
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox