* Per-inferior program arguments and io terminal
@ 2010-01-13 12:44 Vladimir Prus
2010-01-13 15:49 ` Pedro Alves
0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Prus @ 2010-01-13 12:44 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 448 bytes --]
At present, 'set args' sets global program arguments -- for every inferior. So,
if you wish to debug multiple programs, and they have different arguments, things
are unpleasant -- arguments should be changed before running each program. The
same problem exists with tty setting. The latter is probably most important for
frontends.
This patch makes 'set args' and 'set inferior-tty' be per-inferior. No regressions
on i686 linux. OK?
- Volodya
[-- Attachment #2: per-inferior-args.diff --]
[-- Type: text/x-patch, Size: 11966 bytes --]
commit 62c539aad84bf40129de8c8e1232af7c332885b1
Author: Vladimir Prus <vladimir@codesourcery.com>
Date: Mon Dec 21 15:28:03 2009 +0300
Per-inferior args and tty.
* infcmd.c (inferior_args): Rename to ...
(inferior_args_sctach): ... this.
(inferior_io_terminal): Rename to ...
(inferior_io_terminal_scratch): ... this.
(inferior_argc, inferior_argv): Remove.
(set_inferior_io_terminal, get_inferior_io_terminal): Store
inside current_inferior().
(notice_inferior_io_terminal_set, show_inferior_io_terminal): New.
(get_inferior_args, set_inferior_args): Store inside
current_inferior().
(set_inferior_args_vector, notice_args_set): Likewise.
(tty_command): Remove.
(run_command_1): Don't free old args, as they are feed by
set_inferior_arg now.
(run_no_args_command): Likewise.
(_initialize_infcmd): Adjust variables.
* inferior.h (set_inferior_arg): Adjust prototype.
(struct inferior): New fields args, argc, argv, terminal.
* main.c (captured_main): Set arguments only after the initial
inferior has been created. Set set_inferior_io_terminal,
not tty_command.
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 21a2233..f0804b8 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -126,20 +126,17 @@ void _initialize_infcmd (void);
#define ERROR_NO_INFERIOR \
if (!target_has_execution) error (_("The program is not being run."));
-/* String containing arguments to give to the program, separated by spaces.
- Empty string (pointer to '\0') means no args. */
+/* Scratch area where string containing arguments to give to the program will be
+ stored by 'set args'. As soon as anything is stored, notice_args_set will
+ move it into per-inferior storage. Arguments are separated by spaces. Empty
+ string (pointer to '\0') means no args. */
-static char *inferior_args;
+static char *inferior_args_scratch;
-/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero,
- then we must compute INFERIOR_ARGS from this (via the target). */
+/* Scratch area where 'set inferior-tty' will store user-provided value.
+ We'll immediate copy it into per-inferior storage. */
-static int inferior_argc;
-static char **inferior_argv;
-
-/* File name for default use for standard in/out in the inferior. */
-
-static char *inferior_io_terminal;
+static char *inferior_io_terminal_scratch;
/* Pid of our debugged inferior, or 0 if no inferior now.
Since various parts of infrun.c test this to see whether there is a program
@@ -176,64 +173,74 @@ struct gdb_environ *inferior_environ;
void
set_inferior_io_terminal (const char *terminal_name)
{
- if (inferior_io_terminal)
- xfree (inferior_io_terminal);
-
- if (!terminal_name)
- inferior_io_terminal = NULL;
- else
- inferior_io_terminal = xstrdup (terminal_name);
+ xfree (current_inferior ()->terminal);
+ current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0;
}
const char *
get_inferior_io_terminal (void)
{
- return inferior_io_terminal;
+ return current_inferior ()->terminal;
+}
+
+static void
+notice_inferior_io_terminal_set (char *args, int from_tty, struct cmd_list_element *c)
+{
+ /* CLI has assigned the user-provided value to inferior_io_terminal_scratch.
+ Now route it to current inferior. */
+ set_inferior_io_terminal (inferior_io_terminal_scratch);
+}
+
+static void
+show_inferior_io_terminal (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ deprecated_show_value_hack (file, from_tty, c, get_inferior_io_terminal ());
}
char *
get_inferior_args (void)
{
- if (inferior_argc != 0)
+ if (current_inferior ()->argc != 0)
{
char *n, *old;
- n = construct_inferior_arguments (inferior_argc, inferior_argv);
- old = set_inferior_args (n);
- xfree (old);
+ n = construct_inferior_arguments (current_inferior ()->argc,
+ current_inferior ()->argv);
+ set_inferior_args (n);
}
- if (inferior_args == NULL)
- inferior_args = xstrdup ("");
+ if (current_inferior ()->args == NULL)
+ current_inferior ()->args = xstrdup ("");
- return inferior_args;
+ return current_inferior ()->args;
}
-char *
+void
set_inferior_args (char *newargs)
{
- char *saved_args = inferior_args;
-
- inferior_args = newargs;
- inferior_argc = 0;
- inferior_argv = 0;
-
- return saved_args;
+ xfree (current_inferior ()->args);
+ current_inferior ()->args = xstrdup (newargs ? newargs : "");
+ current_inferior ()->argc = 0;
+ current_inferior ()->argv = 0;
}
void
set_inferior_args_vector (int argc, char **argv)
{
- inferior_argc = argc;
- inferior_argv = argv;
+ current_inferior ()->argc = argc;
+ current_inferior ()->argv = argv;
}
/* Notice when `set args' is run. */
static void
notice_args_set (char *args, int from_tty, struct cmd_list_element *c)
{
- inferior_argc = 0;
- inferior_argv = 0;
+ /* CLI has assigned the user-provided value to inferior_args_scratch.
+ Now route it to current inferior. */
+ set_inferior_args (inferior_args_scratch);
}
/* Notice when `show args' is run. */
@@ -369,15 +376,6 @@ strip_bg_char (char **args)
return 0;
}
-void
-tty_command (char *file, int from_tty)
-{
- if (file == 0)
- error_no_arg (_("terminal name for running target process"));
-
- set_inferior_io_terminal (file);
-}
-
/* Common actions to take after creating any sort of inferior, by any
means (running, attaching, connecting, et cetera). The target
should be stopped. */
@@ -536,10 +534,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
/* If there were other args, beside '&', process them. */
if (args)
- {
- char *old_args = set_inferior_args (xstrdup (args));
- xfree (old_args);
- }
+ set_inferior_args (xstrdup (args));
}
if (from_tty)
@@ -594,8 +589,7 @@ run_command (char *args, int from_tty)
static void
run_no_args_command (char *args, int from_tty)
{
- char *old_args = set_inferior_args (xstrdup (""));
- xfree (old_args);
+ set_inferior_args (xstrdup (""));
}
\f
@@ -2646,14 +2640,17 @@ _initialize_infcmd (void)
/* add the filename of the terminal connected to inferior I/O */
add_setshow_filename_cmd ("inferior-tty", class_run,
- &inferior_io_terminal, _("\
+ &inferior_io_terminal_scratch, _("\
Set terminal for future runs of program being debugged."), _("\
Show terminal for future runs of program being debugged."), _("\
-Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist);
+Usage: set inferior-tty /dev/pts/1"),
+ notice_inferior_io_terminal_set,
+ show_inferior_io_terminal,
+ &setlist, &showlist);
add_com_alias ("tty", "set inferior-tty", class_alias, 0);
add_setshow_optional_filename_cmd ("args", class_run,
- &inferior_args, _("\
+ &inferior_args_scratch, _("\
Set argument list to give program being debugged when it is started."), _("\
Show argument list to give program being debugged when it is started."), _("\
Follow this command with any number of args, to be passed to the program."),
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 9798ef1..048fc11 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -261,7 +261,7 @@ extern void attach_command (char *, int);
extern char *get_inferior_args (void);
-extern char *set_inferior_args (char *);
+extern void set_inferior_args (char *);
extern void set_inferior_args_vector (int, char **);
@@ -427,6 +427,18 @@ struct inferior
/* The program space bound to this inferior. */
struct program_space *pspace;
+ /* The arguments string to use when running. */
+ char *args;
+
+ /* The size of elements in argv. */
+ int argc;
+
+ /* The vector version of arguments. */
+ char **argv;
+
+ /* The name of terminal device to use for I/O. */
+ char *terminal;
+
/* See the definition of stop_kind above. */
enum stop_kind stop_soon;
diff --git a/gdb/main.c b/gdb/main.c
index 0cc0f75..e9f3857 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -631,54 +631,6 @@ extern int gdbtk_test (char *);
use_windows = 0;
}
- if (set_args)
- {
- /* The remaining options are the command-line options for the
- inferior. The first one is the sym/exec file, and the rest
- are arguments. */
- if (optind >= argc)
- {
- fprintf_unfiltered (gdb_stderr,
- _("%s: `--args' specified but no program specified\n"),
- argv[0]);
- exit (1);
- }
- symarg = argv[optind];
- execarg = argv[optind];
- ++optind;
- set_inferior_args_vector (argc - optind, &argv[optind]);
- }
- else
- {
- /* OK, that's all the options. */
-
- /* The first argument, if specified, is the name of the
- executable. */
- if (optind < argc)
- {
- symarg = argv[optind];
- execarg = argv[optind];
- optind++;
- }
-
- /* If the user hasn't already specified a PID or the name of a
- core file, then a second optional argument is allowed. If
- present, this argument should be interpreted as either a
- PID or a core file, whichever works. */
- if (pidarg == NULL && corearg == NULL && optind < argc)
- {
- pid_or_core_arg = argv[optind];
- optind++;
- }
-
- /* Any argument left on the command line is unexpected and
- will be ignored. Inform the user. */
- if (optind < argc)
- fprintf_unfiltered (gdb_stderr, _("\
-Excess command line arguments ignored. (%s%s)\n"),
- argv[optind],
- (optind == argc - 1) ? "" : " ...");
- }
if (batch)
quiet = 1;
}
@@ -687,6 +639,57 @@ Excess command line arguments ignored. (%s%s)\n"),
control of the console via the deprecated_init_ui_hook (). */
gdb_init (argv[0]);
+ /* Now that gdb_init has created the initial inferior, we're in position
+ to set args for that inferior. */
+ if (set_args)
+ {
+ /* The remaining options are the command-line options for the
+ inferior. The first one is the sym/exec file, and the rest
+ are arguments. */
+ if (optind >= argc)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ _("%s: `--args' specified but no program specified\n"),
+ argv[0]);
+ exit (1);
+ }
+ symarg = argv[optind];
+ execarg = argv[optind];
+ ++optind;
+ set_inferior_args_vector (argc - optind, &argv[optind]);
+ }
+ else
+ {
+ /* OK, that's all the options. */
+
+ /* The first argument, if specified, is the name of the
+ executable. */
+ if (optind < argc)
+ {
+ symarg = argv[optind];
+ execarg = argv[optind];
+ optind++;
+ }
+
+ /* If the user hasn't already specified a PID or the name of a
+ core file, then a second optional argument is allowed. If
+ present, this argument should be interpreted as either a
+ PID or a core file, whichever works. */
+ if (pidarg == NULL && corearg == NULL && optind < argc)
+ {
+ pid_or_core_arg = argv[optind];
+ optind++;
+ }
+
+ /* Any argument left on the command line is unexpected and
+ will be ignored. Inform the user. */
+ if (optind < argc)
+ fprintf_unfiltered (gdb_stderr, _("\
+Excess command line arguments ignored. (%s%s)\n"),
+ argv[optind],
+ (optind == argc - 1) ? "" : " ...");
+ }
+
/* Lookup gdbinit files. Note that the gdbinit file name may be overriden
during file initialization, so get_init_files should be called after
gdb_init. */
@@ -840,7 +843,7 @@ Can't attach to process and specify a core file at the same time."));
}
if (ttyarg != NULL)
- catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL);
+ set_inferior_io_terminal (ttyarg);
/* Error messages should no longer be distinguished with extra output. */
error_pre_print = NULL;
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: Per-inferior program arguments and io terminal 2010-01-13 12:44 Per-inferior program arguments and io terminal Vladimir Prus @ 2010-01-13 15:49 ` Pedro Alves 2010-01-14 9:27 ` Vladimir Prus 0 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2010-01-13 15:49 UTC (permalink / raw) To: gdb-patches; +Cc: Vladimir Prus Thanks. IMO, it doesn't make sense to have per-inferior args, but not per-inferior environ. We should give the environ the same treatment now, so that we don't end up with a per-inferior args in 7.1, and per-inferior args and environ in post 7.1. On Wednesday 13 January 2010 12:44:26, Vladimir Prus wrote: > commit 62c539aad84bf40129de8c8e1232af7c332885b1 > Author: Vladimir Prus <vladimir@codesourcery.com> > Date: Mon Dec 21 15:28:03 2009 +0300 > > Per-inferior args and tty. > > * infcmd.c (inferior_args): Rename to ... > (inferior_args_sctach): ... this. Typo. > (inferior_io_terminal): Rename to ... > (inferior_io_terminal_scratch): ... this. > (inferior_argc, inferior_argv): Remove. > (set_inferior_io_terminal, get_inferior_io_terminal): Store > inside current_inferior(). > (notice_inferior_io_terminal_set, show_inferior_io_terminal): New. > (get_inferior_args, set_inferior_args): Store inside > current_inferior(). > (set_inferior_args_vector, notice_args_set): Likewise. > (tty_command): Remove. > (run_command_1): Don't free old args, as they are feed by > set_inferior_arg now. > (run_no_args_command): Likewise. > (_initialize_infcmd): Adjust variables. > * inferior.h (set_inferior_arg): Adjust prototype. > (struct inferior): New fields args, argc, argv, terminal. > * main.c (captured_main): Set arguments only after the initial > inferior has been created. Set set_inferior_io_terminal, > not tty_command. > > diff --git a/gdb/infcmd.c b/gdb/infcmd.c > index 21a2233..f0804b8 100644 > --- a/gdb/infcmd.c > +++ b/gdb/infcmd.c > @@ -126,20 +126,17 @@ void _initialize_infcmd (void); > #define ERROR_NO_INFERIOR \ > if (!target_has_execution) error (_("The program is not being run.")); > > -/* String containing arguments to give to the program, separated by spaces. > - Empty string (pointer to '\0') means no args. */ > +/* Scratch area where string containing arguments to give to the program will be > + stored by 'set args'. As soon as anything is stored, notice_args_set will > + move it into per-inferior storage. Arguments are separated by spaces. Empty > + string (pointer to '\0') means no args. */ > > -static char *inferior_args; > +static char *inferior_args_scratch; > > -/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero, > - then we must compute INFERIOR_ARGS from this (via the target). */ > +/* Scratch area where 'set inferior-tty' will store user-provided value. > + We'll immediate copy it into per-inferior storage. */ > > -static int inferior_argc; > -static char **inferior_argv; > - > -/* File name for default use for standard in/out in the inferior. */ > - > -static char *inferior_io_terminal; > +static char *inferior_io_terminal_scratch; > > /* Pid of our debugged inferior, or 0 if no inferior now. > Since various parts of infrun.c test this to see whether there is a program > @@ -176,64 +173,74 @@ struct gdb_environ *inferior_environ; > void > set_inferior_io_terminal (const char *terminal_name) > { > - if (inferior_io_terminal) > - xfree (inferior_io_terminal); > - > - if (!terminal_name) > - inferior_io_terminal = NULL; > - else > - inferior_io_terminal = xstrdup (terminal_name); > + xfree (current_inferior ()->terminal); > + current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0; > } > > const char * > get_inferior_io_terminal (void) > { > - return inferior_io_terminal; > + return current_inferior ()->terminal; > +} > + > +static void > +notice_inferior_io_terminal_set (char *args, int from_tty, struct cmd_list_element *c) > +{ > + /* CLI has assigned the user-provided value to inferior_io_terminal_scratch. > + Now route it to current inferior. */ > + set_inferior_io_terminal (inferior_io_terminal_scratch); > +} > + > +static void > +show_inferior_io_terminal (struct ui_file *file, int from_tty, > + struct cmd_list_element *c, const char *value) > +{ > + /* Note that we ignore the passed-in value in favor of computing it > + directly. */ > + deprecated_show_value_hack (file, from_tty, c, get_inferior_io_terminal ()); > } Please don't add more deprecated_show_value_hack uses. It's really a nasty hack (it's in cli/cli-setshow.c). It has this gem: /* Print doc minus "show" at start. */ print_doc_line (gdb_stdout, c->doc + 5); This is obviously busted for i18n. Please write something like this instead: fprintf_filtered (gdb_stdout, _("..."), get_inferior_io_terminal ()); > > char * > get_inferior_args (void) > { > - if (inferior_argc != 0) > + if (current_inferior ()->argc != 0) > { > char *n, *old; > > - n = construct_inferior_arguments (inferior_argc, inferior_argv); > - old = set_inferior_args (n); > - xfree (old); > + n = construct_inferior_arguments (current_inferior ()->argc, > + current_inferior ()->argv); > + set_inferior_args (n); > } > > - if (inferior_args == NULL) > - inferior_args = xstrdup (""); > + if (current_inferior ()->args == NULL) > + current_inferior ()->args = xstrdup (""); > > - return inferior_args; > + return current_inferior ()->args; > } > > -char * > +void > set_inferior_args (char *newargs) > { > - char *saved_args = inferior_args; > - > - inferior_args = newargs; > - inferior_argc = 0; > - inferior_argv = 0; > - > - return saved_args; > + xfree (current_inferior ()->args); > + current_inferior ()->args = xstrdup (newargs ? newargs : ""); > + current_inferior ()->argc = 0; > + current_inferior ()->argv = 0; > } > > void > set_inferior_args_vector (int argc, char **argv) > { > - inferior_argc = argc; > - inferior_argv = argv; > + current_inferior ()->argc = argc; > + current_inferior ()->argv = argv; > } > > /* Notice when `set args' is run. */ > static void > notice_args_set (char *args, int from_tty, struct cmd_list_element *c) > { > - inferior_argc = 0; > - inferior_argv = 0; > + /* CLI has assigned the user-provided value to inferior_args_scratch. > + Now route it to current inferior. */ > + set_inferior_args (inferior_args_scratch); > } > > /* Notice when `show args' is run. */ > @@ -369,15 +376,6 @@ strip_bg_char (char **args) > return 0; > } > > -void > -tty_command (char *file, int from_tty) > -{ > - if (file == 0) > - error_no_arg (_("terminal name for running target process")); > - > - set_inferior_io_terminal (file); > -} If you're removing this, please delete the declaration in inferior.h as well. A generic comment: it is good (and the common practice) to name the FOO command callbacks as "FOO_command" or "set_FOO_command"/"show_FOO_command", so that we can find a command implementation easily by just guessing and grepping. > - > /* Common actions to take after creating any sort of inferior, by any > means (running, attaching, connecting, et cetera). The target > should be stopped. */ > @@ -536,10 +534,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) > > /* If there were other args, beside '&', process them. */ > if (args) > - { > - char *old_args = set_inferior_args (xstrdup (args)); > - xfree (old_args); > - } > + set_inferior_args (xstrdup (args)); There's inconsistency in the `args' memory managent. set_inferior_args already xstrdups the incoming argument. What should stay? Can we have a short comment in set_inferior_args's decription mentioning who's supposed to manage the args' memory? > } > > if (from_tty) > @@ -594,8 +589,7 @@ run_command (char *args, int from_tty) > static void > run_no_args_command (char *args, int from_tty) > { > - char *old_args = set_inferior_args (xstrdup ("")); > - xfree (old_args); > + set_inferior_args (xstrdup ("")); > } > \f likewise. > > @@ -2646,14 +2640,17 @@ _initialize_infcmd (void) > > /* add the filename of the terminal connected to inferior I/O */ > add_setshow_filename_cmd ("inferior-tty", class_run, > - &inferior_io_terminal, _("\ > + &inferior_io_terminal_scratch, _("\ > Set terminal for future runs of program being debugged."), _("\ > Show terminal for future runs of program being debugged."), _("\ > -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); > +Usage: set inferior-tty /dev/pts/1"), > + notice_inferior_io_terminal_set, > + show_inferior_io_terminal, > + &setlist, &showlist); > add_com_alias ("tty", "set inferior-tty", class_alias, 0); > > add_setshow_optional_filename_cmd ("args", class_run, > - &inferior_args, _("\ > + &inferior_args_scratch, _("\ > Set argument list to give program being debugged when it is started."), _("\ > Show argument list to give program being debugged when it is started."), _("\ > Follow this command with any number of args, to be passed to the program."), > diff --git a/gdb/inferior.h b/gdb/inferior.h > index 9798ef1..048fc11 100644 > --- a/gdb/inferior.h > +++ b/gdb/inferior.h > @@ -261,7 +261,7 @@ extern void attach_command (char *, int); > > extern char *get_inferior_args (void); > > -extern char *set_inferior_args (char *); > +extern void set_inferior_args (char *); > > extern void set_inferior_args_vector (int, char **); > > @@ -427,6 +427,18 @@ struct inferior > /* The program space bound to this inferior. */ > struct program_space *pspace; > > + /* The arguments string to use when running. */ > + char *args; > + > + /* The size of elements in argv. */ > + int argc; > + > + /* The vector version of arguments. */ > + char **argv; > + > + /* The name of terminal device to use for I/O. */ > + char *terminal; > + These are all leaking when the inferior is deleted. > /* See the definition of stop_kind above. */ > enum stop_kind stop_soon; > > diff --git a/gdb/main.c b/gdb/main.c > index 0cc0f75..e9f3857 100644 > --- a/gdb/main.c > +++ b/gdb/main.c > @@ -631,54 +631,6 @@ extern int gdbtk_test (char *); > use_windows = 0; > } > > - if (set_args) > - { > - /* The remaining options are the command-line options for the > - inferior. The first one is the sym/exec file, and the rest > - are arguments. */ > - if (optind >= argc) > - { > - fprintf_unfiltered (gdb_stderr, > - _("%s: `--args' specified but no program specified\n"), > - argv[0]); > - exit (1); > - } > - symarg = argv[optind]; > - execarg = argv[optind]; > - ++optind; > - set_inferior_args_vector (argc - optind, &argv[optind]); > - } > - else > - { > - /* OK, that's all the options. */ > - > - /* The first argument, if specified, is the name of the > - executable. */ > - if (optind < argc) > - { > - symarg = argv[optind]; > - execarg = argv[optind]; > - optind++; > - } > - > - /* If the user hasn't already specified a PID or the name of a > - core file, then a second optional argument is allowed. If > - present, this argument should be interpreted as either a > - PID or a core file, whichever works. */ > - if (pidarg == NULL && corearg == NULL && optind < argc) > - { > - pid_or_core_arg = argv[optind]; > - optind++; > - } > - > - /* Any argument left on the command line is unexpected and > - will be ignored. Inform the user. */ > - if (optind < argc) > - fprintf_unfiltered (gdb_stderr, _("\ > -Excess command line arguments ignored. (%s%s)\n"), > - argv[optind], > - (optind == argc - 1) ? "" : " ..."); > - } > if (batch) > quiet = 1; > } > @@ -687,6 +639,57 @@ Excess command line arguments ignored. (%s%s)\n"), > control of the console via the deprecated_init_ui_hook (). */ > gdb_init (argv[0]); > > + /* Now that gdb_init has created the initial inferior, we're in position > + to set args for that inferior. */ > + if (set_args) > + { > + /* The remaining options are the command-line options for the > + inferior. The first one is the sym/exec file, and the rest > + are arguments. */ > + if (optind >= argc) > + { > + fprintf_unfiltered (gdb_stderr, > + _("%s: `--args' specified but no program specified\n"), > + argv[0]); > + exit (1); > + } > + symarg = argv[optind]; > + execarg = argv[optind]; > + ++optind; > + set_inferior_args_vector (argc - optind, &argv[optind]); > + } > + else > + { > + /* OK, that's all the options. */ > + > + /* The first argument, if specified, is the name of the > + executable. */ > + if (optind < argc) > + { > + symarg = argv[optind]; > + execarg = argv[optind]; > + optind++; > + } > + > + /* If the user hasn't already specified a PID or the name of a > + core file, then a second optional argument is allowed. If > + present, this argument should be interpreted as either a > + PID or a core file, whichever works. */ > + if (pidarg == NULL && corearg == NULL && optind < argc) > + { > + pid_or_core_arg = argv[optind]; > + optind++; > + } > + > + /* Any argument left on the command line is unexpected and > + will be ignored. Inform the user. */ > + if (optind < argc) > + fprintf_unfiltered (gdb_stderr, _("\ > +Excess command line arguments ignored. (%s%s)\n"), > + argv[optind], > + (optind == argc - 1) ? "" : " ..."); > + } > + > /* Lookup gdbinit files. Note that the gdbinit file name may be overriden > during file initialization, so get_init_files should be called after > gdb_init. */ > @@ -840,7 +843,7 @@ Can't attach to process and specify a core file at the same time.")); > } > > if (ttyarg != NULL) > - catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); > + set_inferior_io_terminal (ttyarg); > > /* Error messages should no longer be distinguished with extra output. */ > error_pre_print = NULL; ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-13 15:49 ` Pedro Alves @ 2010-01-14 9:27 ` Vladimir Prus 2010-01-14 13:38 ` Pedro Alves 0 siblings, 1 reply; 9+ messages in thread From: Vladimir Prus @ 2010-01-14 9:27 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches [-- Attachment #1: Type: Text/Plain, Size: 3852 bytes --] On Wednesday 13 January 2010 18:49:15 Pedro Alves wrote: > > -void > > -tty_command (char *file, int from_tty) > > -{ > > - if (file == 0) > > - error_no_arg (_("terminal name for running target process")); > > - > > - set_inferior_io_terminal (file); > > -} > > If you're removing this, please delete the declaration in > inferior.h as well. > > > A generic comment: it is good (and the common practice) to name > the FOO command callbacks as "FOO_command" or > "set_FOO_command"/"show_FOO_command", so that we can find a command > implementation easily by just guessing and grepping. I am not sure I follow you. tty_command, although named as FOO_command, was not actually used as command anywhere I can see. Or do you refer to some other function? > > /* Common actions to take after creating any sort of inferior, by any > > means (running, attaching, connecting, et cetera). The target > > should be stopped. */ > > @@ -536,10 +534,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) > > > > /* If there were other args, beside '&', process them. */ > > if (args) > > - { > > - char *old_args = set_inferior_args (xstrdup (args)); > > - xfree (old_args); > > - } > > + set_inferior_args (xstrdup (args)); > > There's inconsistency in the `args' memory managent. set_inferior_args > already xstrdups the incoming argument. What should stay? Can we have a > short comment in set_inferior_args's decription mentioning > who's supposed to manage the args' memory? /me wishes for std::string (and/or boost::shared_ptr) Fixed. > > @@ -2646,14 +2640,17 @@ _initialize_infcmd (void) > > > > /* add the filename of the terminal connected to inferior I/O */ > > add_setshow_filename_cmd ("inferior-tty", class_run, > > - &inferior_io_terminal, _("\ > > + &inferior_io_terminal_scratch, _("\ > > Set terminal for future runs of program being debugged."), _("\ > > Show terminal for future runs of program being debugged."), _("\ > > -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); > > +Usage: set inferior-tty /dev/pts/1"), > > + notice_inferior_io_terminal_set, > > + show_inferior_io_terminal, > > + &setlist, &showlist); > > add_com_alias ("tty", "set inferior-tty", class_alias, 0); > > > > add_setshow_optional_filename_cmd ("args", class_run, > > - &inferior_args, _("\ > > + &inferior_args_scratch, _("\ > > Set argument list to give program being debugged when it is started."), _("\ > > Show argument list to give program being debugged when it is started."), _("\ > > Follow this command with any number of args, to be passed to the program."), > > diff --git a/gdb/inferior.h b/gdb/inferior.h > > index 9798ef1..048fc11 100644 > > --- a/gdb/inferior.h > > +++ b/gdb/inferior.h > > @@ -261,7 +261,7 @@ extern void attach_command (char *, int); > > > > extern char *get_inferior_args (void); > > > > -extern char *set_inferior_args (char *); > > +extern void set_inferior_args (char *); > > > > extern void set_inferior_args_vector (int, char **); > > > > @@ -427,6 +427,18 @@ struct inferior > > /* The program space bound to this inferior. */ > > struct program_space *pspace; > > > > + /* The arguments string to use when running. */ > > + char *args; > > + > > + /* The size of elements in argv. */ > > + int argc; > > + > > + /* The vector version of arguments. */ > > + char **argv; > > + > > + /* The name of terminal device to use for I/O. */ > > + char *terminal; > > + > > These are all leaking when the inferior is deleted. Here's a revised version. - Volodya [-- Attachment #2: per-inferior-args2.diff --] [-- Type: text/x-patch, Size: 20445 bytes --] commit 79ceacd2842d1939510443f0e5ee35f38439a447 Author: Vladimir Prus <vladimir@codesourcery.com> Date: Mon Dec 21 15:28:03 2009 +0300 Per-inferior args and tty. * infcmd.c (inferior_args): Rename to ... (inferior_args_scratch): ... this. (inferior_io_terminal): Rename to ... (inferior_io_terminal_scratch): ... this. (inferior_argc, inferior_argv): Remove. (set_inferior_io_terminal, get_inferior_io_terminal): Store inside current_inferior(). (notice_inferior_io_terminal_set, show_inferior_io_terminal): New. (get_inferior_args, set_inferior_args): Store inside current_inferior(). (set_inferior_args_vector, notice_args_set): Likewise. (tty_command): Remove. (run_command_1): Don't free old args, as they are feed by set_inferior_arg now. (run_no_args_command): Likewise. (inferior_environ): Remove. (run_command_1): Use environemnt of the current inferior. (environtment_info, set_environment_command) (unset_environment_command, path_info, path_command): Likewise. (_initialize_infcmd): Adjust variables. Do no init inferior_environ. * inferior.h (set_inferior_arg): Adjust prototype. (struct inferior): New fields args, argc, argv, terminal, environment. (inferior_environ): Remove declaration. * inferior.c (free_inferior): Free new fields. (add_inferior_silent): Initialize 'environment' field. * main.c (captured_main): Set arguments only after the initial inferior has been created. Set set_inferior_io_terminal, not tty_command. * mi/mi-main.c (mi_cmd_env_path): Use environemnt of the current inferior. (_initialize_mi_cmd_env): Adjust for disappearance of global inferior_environ. * solib.c (solib_find): Use environment of the current inferior. diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 21a2233..c43e53f 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -126,20 +126,17 @@ void _initialize_infcmd (void); #define ERROR_NO_INFERIOR \ if (!target_has_execution) error (_("The program is not being run.")); -/* String containing arguments to give to the program, separated by spaces. - Empty string (pointer to '\0') means no args. */ +/* Scratch area where string containing arguments to give to the program will be + stored by 'set args'. As soon as anything is stored, notice_args_set will + move it into per-inferior storage. Arguments are separated by spaces. Empty + string (pointer to '\0') means no args. */ -static char *inferior_args; +static char *inferior_args_scratch; -/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero, - then we must compute INFERIOR_ARGS from this (via the target). */ +/* Scratch area where 'set inferior-tty' will store user-provided value. + We'll immediate copy it into per-inferior storage. */ -static int inferior_argc; -static char **inferior_argv; - -/* File name for default use for standard in/out in the inferior. */ - -static char *inferior_io_terminal; +static char *inferior_io_terminal_scratch; /* Pid of our debugged inferior, or 0 if no inferior now. Since various parts of infrun.c test this to see whether there is a program @@ -166,74 +163,89 @@ int stop_stack_dummy; int stopped_by_random_signal; -/* Environment to use for running inferior, - in format described in environ.h. */ - -struct gdb_environ *inferior_environ; \f /* Accessor routines. */ +/* Set the io terminal for the current inferior. Ownership of + TERMINAL_NAME is not transferred. */ + void set_inferior_io_terminal (const char *terminal_name) { - if (inferior_io_terminal) - xfree (inferior_io_terminal); - - if (!terminal_name) - inferior_io_terminal = NULL; - else - inferior_io_terminal = xstrdup (terminal_name); + xfree (current_inferior ()->terminal); + current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0; } const char * get_inferior_io_terminal (void) { - return inferior_io_terminal; + return current_inferior ()->terminal; +} + +static void +notice_inferior_io_terminal_set (char *args, int from_tty, struct cmd_list_element *c) +{ + /* CLI has assigned the user-provided value to inferior_io_terminal_scratch. + Now route it to current inferior. */ + set_inferior_io_terminal (inferior_io_terminal_scratch); +} + +static void +show_inferior_io_terminal (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + /* Note that we ignore the passed-in value in favor of computing it + directly. */ + fprintf_filtered (gdb_stdout, + _("argument list to give program being debugged when it is started is %s"), + get_inferior_io_terminal ()); } char * get_inferior_args (void) { - if (inferior_argc != 0) + if (current_inferior ()->argc != 0) { - char *n, *old; + char *n; - n = construct_inferior_arguments (inferior_argc, inferior_argv); - old = set_inferior_args (n); - xfree (old); + n = construct_inferior_arguments (current_inferior ()->argc, + current_inferior ()->argv); + set_inferior_args (n); + xfree (n); } - if (inferior_args == NULL) - inferior_args = xstrdup (""); + if (current_inferior ()->args == NULL) + current_inferior ()->args = xstrdup (""); - return inferior_args; + return current_inferior ()->args; } -char * +/* Set the arguments for the current inferior. Ownership of + NEWARGS is not transferred. */ + +void set_inferior_args (char *newargs) { - char *saved_args = inferior_args; - - inferior_args = newargs; - inferior_argc = 0; - inferior_argv = 0; - - return saved_args; + xfree (current_inferior ()->args); + current_inferior ()->args = xstrdup (newargs ? newargs : ""); + current_inferior ()->argc = 0; + current_inferior ()->argv = 0; } void set_inferior_args_vector (int argc, char **argv) { - inferior_argc = argc; - inferior_argv = argv; + current_inferior ()->argc = argc; + current_inferior ()->argv = argv; } /* Notice when `set args' is run. */ static void notice_args_set (char *args, int from_tty, struct cmd_list_element *c) { - inferior_argc = 0; - inferior_argv = 0; + /* CLI has assigned the user-provided value to inferior_args_scratch. + Now route it to current inferior. */ + set_inferior_args (inferior_args_scratch); } /* Notice when `show args' is run. */ @@ -369,15 +381,6 @@ strip_bg_char (char **args) return 0; } -void -tty_command (char *file, int from_tty) -{ - if (file == 0) - error_no_arg (_("terminal name for running target process")); - - set_inferior_io_terminal (file); -} - /* Common actions to take after creating any sort of inferior, by any means (running, attaching, connecting, et cetera). The target should be stopped. */ @@ -536,10 +539,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* If there were other args, beside '&', process them. */ if (args) - { - char *old_args = set_inferior_args (xstrdup (args)); - xfree (old_args); - } + set_inferior_args (args); } if (from_tty) @@ -559,7 +559,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* We call get_inferior_args() because we might need to compute the value now. */ target_create_inferior (exec_file, get_inferior_args (), - environ_vector (inferior_environ), from_tty); + environ_vector (current_inferior ()->environment), from_tty); /* We're starting off a new process. When we get out of here, in non-stop mode, finish the state of all threads of that process, @@ -594,8 +594,7 @@ run_command (char *args, int from_tty) static void run_no_args_command (char *args, int from_tty) { - char *old_args = set_inferior_args (xstrdup ("")); - xfree (old_args); + set_inferior_args (""); } \f @@ -1699,7 +1698,7 @@ environment_info (char *var, int from_tty) { if (var) { - char *val = get_in_environ (inferior_environ, var); + char *val = get_in_environ (current_inferior ()->environment, var); if (val) { puts_filtered (var); @@ -1716,7 +1715,7 @@ environment_info (char *var, int from_tty) } else { - char **vector = environ_vector (inferior_environ); + char **vector = environ_vector (current_inferior ()->environment); while (*vector) { puts_filtered (*vector++); @@ -1781,10 +1780,10 @@ set_environment_command (char *arg, int from_tty) printf_filtered (_("\ Setting environment variable \"%s\" to null value.\n"), var); - set_in_environ (inferior_environ, var, ""); + set_in_environ (current_inferior ()->environment, var, ""); } else - set_in_environ (inferior_environ, var, val); + set_in_environ (current_inferior ()->environment, var, val); xfree (var); } @@ -1797,12 +1796,12 @@ unset_environment_command (char *var, int from_tty) Ask for confirmation if reading from the terminal. */ if (!from_tty || query (_("Delete all environment variables? "))) { - free_environ (inferior_environ); - inferior_environ = make_environ (); + free_environ (current_inferior ()->environment); + current_inferior ()->environment = make_environ (); } } else - unset_in_environ (inferior_environ, var); + unset_in_environ (current_inferior ()->environment, var); } /* Handle the execution path (PATH variable) */ @@ -1813,7 +1812,7 @@ static void path_info (char *args, int from_tty) { puts_filtered ("Executable and object file path: "); - puts_filtered (get_in_environ (inferior_environ, path_var_name)); + puts_filtered (get_in_environ (current_inferior ()->environment, path_var_name)); puts_filtered ("\n"); } @@ -1825,13 +1824,13 @@ path_command (char *dirname, int from_tty) char *exec_path; char *env; dont_repeat (); - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); /* Can be null if path is not set */ if (!env) env = ""; exec_path = xstrdup (env); mod_path (dirname, &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); + set_in_environ (current_inferior ()->environment, path_var_name, exec_path); xfree (exec_path); if (from_tty) path_info ((char *) NULL, from_tty); @@ -2646,14 +2645,17 @@ _initialize_infcmd (void) /* add the filename of the terminal connected to inferior I/O */ add_setshow_filename_cmd ("inferior-tty", class_run, - &inferior_io_terminal, _("\ + &inferior_io_terminal_scratch, _("\ Set terminal for future runs of program being debugged."), _("\ Show terminal for future runs of program being debugged."), _("\ -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); +Usage: set inferior-tty /dev/pts/1"), + notice_inferior_io_terminal_set, + show_inferior_io_terminal, + &setlist, &showlist); add_com_alias ("tty", "set inferior-tty", class_alias, 0); add_setshow_optional_filename_cmd ("args", class_run, - &inferior_args, _("\ + &inferior_args_scratch, _("\ Set argument list to give program being debugged when it is started."), _("\ Show argument list to give program being debugged when it is started."), _("\ Follow this command with any number of args, to be passed to the program."), @@ -2855,7 +2857,4 @@ Register name as argument means describe only that register.")); add_info ("vector", vector_info, _("Print the status of the vector unit\n")); - - inferior_environ = make_environ (); - init_environ (inferior_environ); } diff --git a/gdb/inferior.c b/gdb/inferior.c index d27a3e3..1ac5dfa 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -29,6 +29,7 @@ #include "gdbthread.h" #include "gdbcore.h" #include "symfile.h" +#include "environ.h" void _initialize_inferiors (void); @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) { discard_all_inferior_continuations (inf); inferior_free_data (inf); + xfree (inf->args); + xfree (inf->argv); + xfree (inf->terminal); + free_environ (inf->environment); xfree (inf->private); xfree (inf); } @@ -124,6 +129,9 @@ add_inferior_silent (int pid) inf->next = inferior_list; inferior_list = inf; + inf->environment = make_environ (); + init_environ (inf->environment); + inferior_alloc_data (inf); if (pid != 0) diff --git a/gdb/inferior.h b/gdb/inferior.h index 9798ef1..fd1beff 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -131,8 +131,6 @@ extern int sync_execution; /* Inferior environment. */ -extern struct gdb_environ *inferior_environ; - extern void clear_proceed_status (void); extern void proceed (CORE_ADDR, enum target_signal, int); @@ -253,15 +251,13 @@ void set_step_info (struct frame_info *frame, struct symtab_and_line sal); /* From infcmd.c */ -extern void tty_command (char *, int); - extern void post_create_inferior (struct target_ops *, int); extern void attach_command (char *, int); extern char *get_inferior_args (void); -extern char *set_inferior_args (char *); +extern void set_inferior_args (char *); extern void set_inferior_args_vector (int, char **); @@ -427,6 +423,22 @@ struct inferior /* The program space bound to this inferior. */ struct program_space *pspace; + /* The arguments string to use when running. */ + char *args; + + /* The size of elements in argv. */ + int argc; + + /* The vector version of arguments. */ + char **argv; + + /* The name of terminal device to use for I/O. */ + char *terminal; + + /* Environment to use for running inferior, + in format described in environ.h. */ + struct gdb_environ *environment; + /* See the definition of stop_kind above. */ enum stop_kind stop_soon; diff --git a/gdb/main.c b/gdb/main.c index 0cc0f75..e9f3857 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -631,54 +631,6 @@ extern int gdbtk_test (char *); use_windows = 0; } - if (set_args) - { - /* The remaining options are the command-line options for the - inferior. The first one is the sym/exec file, and the rest - are arguments. */ - if (optind >= argc) - { - fprintf_unfiltered (gdb_stderr, - _("%s: `--args' specified but no program specified\n"), - argv[0]); - exit (1); - } - symarg = argv[optind]; - execarg = argv[optind]; - ++optind; - set_inferior_args_vector (argc - optind, &argv[optind]); - } - else - { - /* OK, that's all the options. */ - - /* The first argument, if specified, is the name of the - executable. */ - if (optind < argc) - { - symarg = argv[optind]; - execarg = argv[optind]; - optind++; - } - - /* If the user hasn't already specified a PID or the name of a - core file, then a second optional argument is allowed. If - present, this argument should be interpreted as either a - PID or a core file, whichever works. */ - if (pidarg == NULL && corearg == NULL && optind < argc) - { - pid_or_core_arg = argv[optind]; - optind++; - } - - /* Any argument left on the command line is unexpected and - will be ignored. Inform the user. */ - if (optind < argc) - fprintf_unfiltered (gdb_stderr, _("\ -Excess command line arguments ignored. (%s%s)\n"), - argv[optind], - (optind == argc - 1) ? "" : " ..."); - } if (batch) quiet = 1; } @@ -687,6 +639,57 @@ Excess command line arguments ignored. (%s%s)\n"), control of the console via the deprecated_init_ui_hook (). */ gdb_init (argv[0]); + /* Now that gdb_init has created the initial inferior, we're in position + to set args for that inferior. */ + if (set_args) + { + /* The remaining options are the command-line options for the + inferior. The first one is the sym/exec file, and the rest + are arguments. */ + if (optind >= argc) + { + fprintf_unfiltered (gdb_stderr, + _("%s: `--args' specified but no program specified\n"), + argv[0]); + exit (1); + } + symarg = argv[optind]; + execarg = argv[optind]; + ++optind; + set_inferior_args_vector (argc - optind, &argv[optind]); + } + else + { + /* OK, that's all the options. */ + + /* The first argument, if specified, is the name of the + executable. */ + if (optind < argc) + { + symarg = argv[optind]; + execarg = argv[optind]; + optind++; + } + + /* If the user hasn't already specified a PID or the name of a + core file, then a second optional argument is allowed. If + present, this argument should be interpreted as either a + PID or a core file, whichever works. */ + if (pidarg == NULL && corearg == NULL && optind < argc) + { + pid_or_core_arg = argv[optind]; + optind++; + } + + /* Any argument left on the command line is unexpected and + will be ignored. Inform the user. */ + if (optind < argc) + fprintf_unfiltered (gdb_stderr, _("\ +Excess command line arguments ignored. (%s%s)\n"), + argv[optind], + (optind == argc - 1) ? "" : " ..."); + } + /* Lookup gdbinit files. Note that the gdbinit file name may be overriden during file initialization, so get_init_files should be called after gdb_init. */ @@ -840,7 +843,7 @@ Can't attach to process and specify a core file at the same time.")); } if (ttyarg != NULL) - catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); + set_inferior_io_terminal (ttyarg); /* Error messages should no longer be distinguished with extra output. */ error_pre_print = NULL; diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c index d9703ee..5bb49fd 100644 --- a/gdb/mi/mi-cmd-env.c +++ b/gdb/mi/mi-cmd-env.c @@ -162,7 +162,7 @@ mi_cmd_env_path (char *command, char **argv, int argc) else { /* Otherwise, get current path to modify. */ - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); /* Can be null if path is not set. */ if (!env) @@ -173,9 +173,9 @@ mi_cmd_env_path (char *command, char **argv, int argc) for (i = argc - 1; i >= 0; --i) env_mod_path (argv[i], &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); + set_in_environ (current_inferior ()->environment, path_var_name, exec_path); xfree (exec_path); - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); ui_out_field_string (uiout, "path", env); } @@ -260,10 +260,17 @@ mi_cmd_inferior_tty_show (char *command, char **argv, int argc) void _initialize_mi_cmd_env (void) { + struct gdb_environ *environment; char *env; - /* We want original execution path to reset to, if desired later. */ - env = get_in_environ (inferior_environ, path_var_name); + /* We want original execution path to reset to, if desired later. + At this point, current inferior is not created, so cannot use + current_inferior ()->environment. Also, there's no obvious + place where this code can be moved suchs that it surely run + before any code possibly mangles original PATH. */ + environment = make_environ (); + init_environ (environment); + env = get_in_environ (environment, path_var_name); /* Can be null if path is not set. */ if (!env) diff --git a/gdb/solib.c b/gdb/solib.c index 21006d8..72c4212 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -227,14 +227,16 @@ solib_find (char *in_pathname, int *fd) /* If not found, next search the inferior's $PATH environment variable. */ if (found_file < 0 && gdb_sysroot_is_empty) - found_file = openp (get_in_environ (inferior_environ, "PATH"), + found_file = openp (get_in_environ (current_inferior ()->environment, + "PATH"), OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, &temp_pathname); /* If not found, next search the inferior's $LD_LIBRARY_PATH environment variable. */ if (found_file < 0 && gdb_sysroot_is_empty) - found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"), + found_file = openp (get_in_environ (current_inferior ()->environment, + "LD_LIBRARY_PATH"), OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, &temp_pathname); ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-14 9:27 ` Vladimir Prus @ 2010-01-14 13:38 ` Pedro Alves 2010-01-14 15:09 ` Vladimir Prus 0 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2010-01-14 13:38 UTC (permalink / raw) To: Vladimir Prus; +Cc: gdb-patches Thanks. On Thursday 14 January 2010 09:27:21, Vladimir Prus wrote: > On Wednesday 13 January 2010 18:49:15 Pedro Alves wrote: > > > > -void > > > -tty_command (char *file, int from_tty) > > > -{ > > > - if (file == 0) > > > - error_no_arg (_("terminal name for running target process")); > > > - > > > - set_inferior_io_terminal (file); > > > -} > > > > If you're removing this, please delete the declaration in > > inferior.h as well. > > > > > > A generic comment: it is good (and the common practice) to name > > the FOO command callbacks as "FOO_command" or > > "set_FOO_command"/"show_FOO_command", so that we can find a command > > implementation easily by just guessing and grepping. > > I am not sure I follow you. tty_command, although named as FOO_command, > was not actually used as command anywhere I can see. Sure is: (gdb) tty Argument required (filename to set it to.). (gdb) help tty Set terminal for future runs of program being debugged. Usage: set inferior-tty /dev/pts/1 See: -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); +Usage: set inferior-tty /dev/pts/1"), + notice_inferior_io_terminal_set, + show_inferior_io_terminal, + &setlist, &showlist); add_com_alias ("tty", "set inferior-tty", class_alias, 0); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > Or do you refer to some other function? -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); +Usage: set inferior-tty /dev/pts/1"), + notice_inferior_io_terminal_set, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + show_inferior_io_terminal, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + &setlist, &showlist); add_com_alias ("tty", "set inferior-tty", class_alias, 0); Better choices would be: set_inferior_tty_command/show_inferior_tty_command or set_inferior_tty/show_inferior_tty. On Thursday 14 January 2010 09:27:21, Vladimir Prus wrote: > Per-inferior args and tty. and environ. > > * infcmd.c (inferior_args): Rename to ... > (inferior_args_scratch): ... this. > (inferior_io_terminal): Rename to ... > (inferior_io_terminal_scratch): ... this. > (inferior_argc, inferior_argv): Remove. > (set_inferior_io_terminal, get_inferior_io_terminal): Store > inside current_inferior(). > (notice_inferior_io_terminal_set, show_inferior_io_terminal): New. > (get_inferior_args, set_inferior_args): Store inside > current_inferior(). > (set_inferior_args_vector, notice_args_set): Likewise. > (tty_command): Remove. > (run_command_1): Don't free old args, as they are feed by > set_inferior_arg now. Typo, "feed". > (run_no_args_command): Likewise. > (inferior_environ): Remove. > (run_command_1): Use environemnt of the current inferior. Typo, "environemnt". > (environtment_info, set_environment_command) Typo, "environtment_info". > (unset_environment_command, path_info, path_command): Likewise. > (_initialize_infcmd): Adjust variables. Do no init inferior_environ. Typo, "Do no". > * inferior.h (set_inferior_arg): Adjust prototype. > (struct inferior): New fields args, argc, argv, terminal, environment. > (inferior_environ): Remove declaration. > * inferior.c (free_inferior): Free new fields. > (add_inferior_silent): Initialize 'environment' field. > * main.c (captured_main): Set arguments only after the initial > inferior has been created. Set set_inferior_io_terminal, > not tty_command. > * mi/mi-main.c (mi_cmd_env_path): Use environemnt of the current > inferior. Typo, "environemnt". > (_initialize_mi_cmd_env): Adjust for disappearance of global > inferior_environ. > * solib.c (solib_find): Use environment of the current inferior. > > +static void > +notice_inferior_io_terminal_set (char *args, int from_tty, struct cmd_list_element *c) Line too long. > +{ > + /* CLI has assigned the user-provided value to inferior_io_terminal_scratch. > + Now route it to current inferior. */ > + set_inferior_io_terminal (inferior_io_terminal_scratch); > +} > + > +static void > +show_inferior_io_terminal (struct ui_file *file, int from_tty, > + struct cmd_list_element *c, const char *value) > +{ > + /* Note that we ignore the passed-in value in favor of computing it > + directly. */ > + fprintf_filtered (gdb_stdout, > + _("argument list to give program being debugged when it is started is %s"), Line too long. > + get_inferior_io_terminal ()); > } > > char * > get_inferior_args (void) > { > - if (inferior_argc != 0) > + if (current_inferior ()->argc != 0) > { > - char *n, *old; > + char *n; > > - n = construct_inferior_arguments (inferior_argc, inferior_argv); > - old = set_inferior_args (n); > - xfree (old); > + n = construct_inferior_arguments (current_inferior ()->argc, > + current_inferior ()->argv); > + set_inferior_args (n); > + xfree (n); > } > > - if (inferior_args == NULL) > - inferior_args = xstrdup (""); Nit. there's a mismatch between this here and set_inferior_args: > + if (current_inferior ()->args == NULL) > + current_inferior ()->args = xstrdup (""); > > - return inferior_args; > + return current_inferior ()->args; > } > > -char * > +/* Set the arguments for the current inferior. Ownership of > + NEWARGS is not transferred. */ > + > +void > set_inferior_args (char *newargs) > { > - char *saved_args = inferior_args; > - > - inferior_args = newargs; > - inferior_argc = 0; > - inferior_argv = 0; > - > - return saved_args; > + xfree (current_inferior ()->args); > + current_inferior ()->args = xstrdup (newargs ? newargs : ""); This never leaves NULL args. I guess it could. > + current_inferior ()->argc = 0; > + current_inferior ()->argv = 0; > } > > void > set_inferior_args_vector (int argc, char **argv) > { > - inferior_argc = argc; > - inferior_argv = argv; > + current_inferior ()->argc = argc; > + current_inferior ()->argv = argv; > } > > @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) > { > discard_all_inferior_continuations (inf); > inferior_free_data (inf); > + xfree (inf->args); > + xfree (inf->argv); Hmm, I was going to say that this usually leaks argv[0..argc], and you should use freeargv, but, I now see that the only caller of set_inferior_args_vector is captured_main, and the argc,argv are presently a shallow copy of `main's arguments, so definitely not ok to free this as is. This definitely needs a comment in the description of inferior->argv, expanded from the comment that was in inferior_argv. > + xfree (inf->terminal); > + free_environ (inf->environment); > xfree (inf->private); > xfree (inf); > } -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-14 13:38 ` Pedro Alves @ 2010-01-14 15:09 ` Vladimir Prus 2010-01-14 15:49 ` Pedro Alves 0 siblings, 1 reply; 9+ messages in thread From: Vladimir Prus @ 2010-01-14 15:09 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches [-- Attachment #1: Type: Text/Plain, Size: 1926 bytes --] On Thursday 14 January 2010 16:37:42 Pedro Alves wrote: > > Or do you refer to some other function? > > -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); > +Usage: set inferior-tty /dev/pts/1"), > + notice_inferior_io_terminal_set, > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + show_inferior_io_terminal, > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + &setlist, &showlist); > add_com_alias ("tty", "set inferior-tty", class_alias, 0); > > Better choices would be: set_inferior_tty_command/show_inferior_tty_command > or set_inferior_tty/show_inferior_tty. Done. Also done for args function. > > -char * > > +/* Set the arguments for the current inferior. Ownership of > > + NEWARGS is not transferred. */ > > + > > +void > > set_inferior_args (char *newargs) > > { > > - char *saved_args = inferior_args; > > - > > - inferior_args = newargs; > > - inferior_argc = 0; > > - inferior_argv = 0; > > - > > - return saved_args; > > + xfree (current_inferior ()->args); > > > + current_inferior ()->args = xstrdup (newargs ? newargs : ""); > > This never leaves NULL args. I guess it could. Done so. > > @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) > > { > > discard_all_inferior_continuations (inf); > > inferior_free_data (inf); > > + xfree (inf->args); > > > + xfree (inf->argv); > > Hmm, I was going to say that this usually leaks argv[0..argc], and > you should use freeargv, but, I now see that the only caller > of set_inferior_args_vector is captured_main, and the > argc,argv are presently a shallow copy of `main's arguments, so > definitely not ok to free this as is. This definitely needs a > comment in the description of inferior->argv, expanded from > the comment that was in inferior_argv. I've added a comment. - Volodya [-- Attachment #2: per-inferior-args3.diff --] [-- Type: text/x-patch, Size: 21400 bytes --] commit caba76c43fb2cd6e3d2a42f15ad5dde9d2615fa7 Author: Vladimir Prus <vladimir@codesourcery.com> Date: Mon Dec 21 15:28:03 2009 +0300 Per-inferior args and tty and environment. * infcmd.c (inferior_args): Rename to ... (inferior_args_scratch): ... this. (inferior_io_terminal): Rename to ... (inferior_io_terminal_scratch): ... this. (inferior_argc, inferior_argv): Remove. (set_inferior_io_terminal, get_inferior_io_terminal): Store inside current_inferior(). (set_inferior_tty_command, show_inferior_tty_command): New. (get_inferior_args, set_inferior_args): Store inside current_inferior(). (notice_args_set): Likewise and rename to... (set_args_command): ... this. (set_inferior_args_vector): Likewise. (notice_args_read): Rename to... (show_args_command): ...new. (tty_command): Remove. (run_command_1): Don't free old args, as they are freed by set_inferior_arg now. (run_no_args_command): Likewise. (inferior_environ): Remove. (run_command_1): Use environemnt of the current inferior. (environment_info, set_environment_command) (unset_environment_command, path_info, path_command): Likewise. (_initialize_infcmd): Adjust for function and variable renames. Do not init inferior_environ. * inferior.h (set_inferior_arg): Adjust prototype. (struct inferior): New fields args, argc, argv, terminal, environment. (inferior_environ): Remove declaration. * inferior.c (free_inferior): Free new fields. (add_inferior_silent): Initialize 'environment' field. * main.c (captured_main): Set arguments only after the initial inferior has been created. Set set_inferior_io_terminal, not tty_command. * mi/mi-main.c (mi_cmd_env_path): Use environment of the current inferior. (_initialize_mi_cmd_env): Adjust for disappearance of global inferior_environ. * solib.c (solib_find): Use environment of the current inferior. diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 21a2233..7d5c653 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -126,20 +126,17 @@ void _initialize_infcmd (void); #define ERROR_NO_INFERIOR \ if (!target_has_execution) error (_("The program is not being run.")); -/* String containing arguments to give to the program, separated by spaces. - Empty string (pointer to '\0') means no args. */ +/* Scratch area where string containing arguments to give to the program will be + stored by 'set args'. As soon as anything is stored, notice_args_set will + move it into per-inferior storage. Arguments are separated by spaces. Empty + string (pointer to '\0') means no args. */ -static char *inferior_args; +static char *inferior_args_scratch; -/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero, - then we must compute INFERIOR_ARGS from this (via the target). */ +/* Scratch area where 'set inferior-tty' will store user-provided value. + We'll immediate copy it into per-inferior storage. */ -static int inferior_argc; -static char **inferior_argv; - -/* File name for default use for standard in/out in the inferior. */ - -static char *inferior_io_terminal; +static char *inferior_io_terminal_scratch; /* Pid of our debugged inferior, or 0 if no inferior now. Since various parts of infrun.c test this to see whether there is a program @@ -166,80 +163,97 @@ int stop_stack_dummy; int stopped_by_random_signal; -/* Environment to use for running inferior, - in format described in environ.h. */ - -struct gdb_environ *inferior_environ; \f /* Accessor routines. */ +/* Set the io terminal for the current inferior. Ownership of + TERMINAL_NAME is not transferred. */ + void set_inferior_io_terminal (const char *terminal_name) { - if (inferior_io_terminal) - xfree (inferior_io_terminal); - - if (!terminal_name) - inferior_io_terminal = NULL; - else - inferior_io_terminal = xstrdup (terminal_name); + xfree (current_inferior ()->terminal); + current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0; } const char * get_inferior_io_terminal (void) { - return inferior_io_terminal; + return current_inferior ()->terminal; +} + +static void +set_inferior_tty_command (char *args, int from_tty, + struct cmd_list_element *c) +{ + /* CLI has assigned the user-provided value to inferior_io_terminal_scratch. + Now route it to current inferior. */ + set_inferior_io_terminal (inferior_io_terminal_scratch); +} + +static void +show_inferior_tty_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + /* Note that we ignore the passed-in value in favor of computing it + directly. */ + fprintf_filtered (gdb_stdout, + _("argument list to give program being debugged when " + "it is started is %s"), + get_inferior_io_terminal ()); } char * get_inferior_args (void) { - if (inferior_argc != 0) + if (current_inferior ()->argc != 0) { - char *n, *old; + char *n; - n = construct_inferior_arguments (inferior_argc, inferior_argv); - old = set_inferior_args (n); - xfree (old); + n = construct_inferior_arguments (current_inferior ()->argc, + current_inferior ()->argv); + set_inferior_args (n); + xfree (n); } - if (inferior_args == NULL) - inferior_args = xstrdup (""); + if (current_inferior ()->args == NULL) + current_inferior ()->args = xstrdup (""); - return inferior_args; + return current_inferior ()->args; } -char * +/* Set the arguments for the current inferior. Ownership of + NEWARGS is not transferred. */ + +void set_inferior_args (char *newargs) { - char *saved_args = inferior_args; - - inferior_args = newargs; - inferior_argc = 0; - inferior_argv = 0; - - return saved_args; + xfree (current_inferior ()->args); + current_inferior ()->args = newargs ? xstrdup (newargs) : NULL; + current_inferior ()->argc = 0; + current_inferior ()->argv = 0; } void set_inferior_args_vector (int argc, char **argv) { - inferior_argc = argc; - inferior_argv = argv; + current_inferior ()->argc = argc; + current_inferior ()->argv = argv; } /* Notice when `set args' is run. */ static void -notice_args_set (char *args, int from_tty, struct cmd_list_element *c) +set_args_command (char *args, int from_tty, struct cmd_list_element *c) { - inferior_argc = 0; - inferior_argv = 0; + /* CLI has assigned the user-provided value to inferior_args_scratch. + Now route it to current inferior. */ + set_inferior_args (inferior_args_scratch); } /* Notice when `show args' is run. */ static void -notice_args_read (struct ui_file *file, int from_tty, - struct cmd_list_element *c, const char *value) +show_args_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) { /* Note that we ignore the passed-in value in favor of computing it directly. */ @@ -369,15 +383,6 @@ strip_bg_char (char **args) return 0; } -void -tty_command (char *file, int from_tty) -{ - if (file == 0) - error_no_arg (_("terminal name for running target process")); - - set_inferior_io_terminal (file); -} - /* Common actions to take after creating any sort of inferior, by any means (running, attaching, connecting, et cetera). The target should be stopped. */ @@ -536,10 +541,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* If there were other args, beside '&', process them. */ if (args) - { - char *old_args = set_inferior_args (xstrdup (args)); - xfree (old_args); - } + set_inferior_args (args); } if (from_tty) @@ -559,7 +561,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* We call get_inferior_args() because we might need to compute the value now. */ target_create_inferior (exec_file, get_inferior_args (), - environ_vector (inferior_environ), from_tty); + environ_vector (current_inferior ()->environment), from_tty); /* We're starting off a new process. When we get out of here, in non-stop mode, finish the state of all threads of that process, @@ -594,8 +596,7 @@ run_command (char *args, int from_tty) static void run_no_args_command (char *args, int from_tty) { - char *old_args = set_inferior_args (xstrdup ("")); - xfree (old_args); + set_inferior_args (""); } \f @@ -1699,7 +1700,7 @@ environment_info (char *var, int from_tty) { if (var) { - char *val = get_in_environ (inferior_environ, var); + char *val = get_in_environ (current_inferior ()->environment, var); if (val) { puts_filtered (var); @@ -1716,7 +1717,7 @@ environment_info (char *var, int from_tty) } else { - char **vector = environ_vector (inferior_environ); + char **vector = environ_vector (current_inferior ()->environment); while (*vector) { puts_filtered (*vector++); @@ -1781,10 +1782,10 @@ set_environment_command (char *arg, int from_tty) printf_filtered (_("\ Setting environment variable \"%s\" to null value.\n"), var); - set_in_environ (inferior_environ, var, ""); + set_in_environ (current_inferior ()->environment, var, ""); } else - set_in_environ (inferior_environ, var, val); + set_in_environ (current_inferior ()->environment, var, val); xfree (var); } @@ -1797,12 +1798,12 @@ unset_environment_command (char *var, int from_tty) Ask for confirmation if reading from the terminal. */ if (!from_tty || query (_("Delete all environment variables? "))) { - free_environ (inferior_environ); - inferior_environ = make_environ (); + free_environ (current_inferior ()->environment); + current_inferior ()->environment = make_environ (); } } else - unset_in_environ (inferior_environ, var); + unset_in_environ (current_inferior ()->environment, var); } /* Handle the execution path (PATH variable) */ @@ -1813,7 +1814,7 @@ static void path_info (char *args, int from_tty) { puts_filtered ("Executable and object file path: "); - puts_filtered (get_in_environ (inferior_environ, path_var_name)); + puts_filtered (get_in_environ (current_inferior ()->environment, path_var_name)); puts_filtered ("\n"); } @@ -1825,13 +1826,13 @@ path_command (char *dirname, int from_tty) char *exec_path; char *env; dont_repeat (); - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); /* Can be null if path is not set */ if (!env) env = ""; exec_path = xstrdup (env); mod_path (dirname, &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); + set_in_environ (current_inferior ()->environment, path_var_name, exec_path); xfree (exec_path); if (from_tty) path_info ((char *) NULL, from_tty); @@ -2646,19 +2647,22 @@ _initialize_infcmd (void) /* add the filename of the terminal connected to inferior I/O */ add_setshow_filename_cmd ("inferior-tty", class_run, - &inferior_io_terminal, _("\ + &inferior_io_terminal_scratch, _("\ Set terminal for future runs of program being debugged."), _("\ Show terminal for future runs of program being debugged."), _("\ -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); +Usage: set inferior-tty /dev/pts/1"), + set_inferior_tty_command, + show_inferior_tty_command, + &setlist, &showlist); add_com_alias ("tty", "set inferior-tty", class_alias, 0); add_setshow_optional_filename_cmd ("args", class_run, - &inferior_args, _("\ + &inferior_args_scratch, _("\ Set argument list to give program being debugged when it is started."), _("\ Show argument list to give program being debugged when it is started."), _("\ Follow this command with any number of args, to be passed to the program."), - notice_args_set, - notice_args_read, + set_args_command, + show_args_command, &setlist, &showlist); c = add_cmd ("environment", no_class, environment_info, _("\ @@ -2855,7 +2859,4 @@ Register name as argument means describe only that register.")); add_info ("vector", vector_info, _("Print the status of the vector unit\n")); - - inferior_environ = make_environ (); - init_environ (inferior_environ); } diff --git a/gdb/inferior.c b/gdb/inferior.c index d27a3e3..1ac5dfa 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -29,6 +29,7 @@ #include "gdbthread.h" #include "gdbcore.h" #include "symfile.h" +#include "environ.h" void _initialize_inferiors (void); @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) { discard_all_inferior_continuations (inf); inferior_free_data (inf); + xfree (inf->args); + xfree (inf->argv); + xfree (inf->terminal); + free_environ (inf->environment); xfree (inf->private); xfree (inf); } @@ -124,6 +129,9 @@ add_inferior_silent (int pid) inf->next = inferior_list; inferior_list = inf; + inf->environment = make_environ (); + init_environ (inf->environment); + inferior_alloc_data (inf); if (pid != 0) diff --git a/gdb/inferior.h b/gdb/inferior.h index 9798ef1..69b7a35 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -131,8 +131,6 @@ extern int sync_execution; /* Inferior environment. */ -extern struct gdb_environ *inferior_environ; - extern void clear_proceed_status (void); extern void proceed (CORE_ADDR, enum target_signal, int); @@ -253,15 +251,13 @@ void set_step_info (struct frame_info *frame, struct symtab_and_line sal); /* From infcmd.c */ -extern void tty_command (char *, int); - extern void post_create_inferior (struct target_ops *, int); extern void attach_command (char *, int); extern char *get_inferior_args (void); -extern char *set_inferior_args (char *); +extern void set_inferior_args (char *); extern void set_inferior_args_vector (int, char **); @@ -427,6 +423,25 @@ struct inferior /* The program space bound to this inferior. */ struct program_space *pspace; + /* The arguments string to use when running. */ + char *args; + + /* The size of elements in argv. */ + int argc; + + /* The vector version of arguments. If ARGC is nonzero, + then we must compute ARGS from this (via the target). + This must always be a 'shallow' copy, and argv[N] should + not be freed. */ + char **argv; + + /* The name of terminal device to use for I/O. */ + char *terminal; + + /* Environment to use for running inferior, + in format described in environ.h. */ + struct gdb_environ *environment; + /* See the definition of stop_kind above. */ enum stop_kind stop_soon; diff --git a/gdb/main.c b/gdb/main.c index 0cc0f75..e9f3857 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -631,54 +631,6 @@ extern int gdbtk_test (char *); use_windows = 0; } - if (set_args) - { - /* The remaining options are the command-line options for the - inferior. The first one is the sym/exec file, and the rest - are arguments. */ - if (optind >= argc) - { - fprintf_unfiltered (gdb_stderr, - _("%s: `--args' specified but no program specified\n"), - argv[0]); - exit (1); - } - symarg = argv[optind]; - execarg = argv[optind]; - ++optind; - set_inferior_args_vector (argc - optind, &argv[optind]); - } - else - { - /* OK, that's all the options. */ - - /* The first argument, if specified, is the name of the - executable. */ - if (optind < argc) - { - symarg = argv[optind]; - execarg = argv[optind]; - optind++; - } - - /* If the user hasn't already specified a PID or the name of a - core file, then a second optional argument is allowed. If - present, this argument should be interpreted as either a - PID or a core file, whichever works. */ - if (pidarg == NULL && corearg == NULL && optind < argc) - { - pid_or_core_arg = argv[optind]; - optind++; - } - - /* Any argument left on the command line is unexpected and - will be ignored. Inform the user. */ - if (optind < argc) - fprintf_unfiltered (gdb_stderr, _("\ -Excess command line arguments ignored. (%s%s)\n"), - argv[optind], - (optind == argc - 1) ? "" : " ..."); - } if (batch) quiet = 1; } @@ -687,6 +639,57 @@ Excess command line arguments ignored. (%s%s)\n"), control of the console via the deprecated_init_ui_hook (). */ gdb_init (argv[0]); + /* Now that gdb_init has created the initial inferior, we're in position + to set args for that inferior. */ + if (set_args) + { + /* The remaining options are the command-line options for the + inferior. The first one is the sym/exec file, and the rest + are arguments. */ + if (optind >= argc) + { + fprintf_unfiltered (gdb_stderr, + _("%s: `--args' specified but no program specified\n"), + argv[0]); + exit (1); + } + symarg = argv[optind]; + execarg = argv[optind]; + ++optind; + set_inferior_args_vector (argc - optind, &argv[optind]); + } + else + { + /* OK, that's all the options. */ + + /* The first argument, if specified, is the name of the + executable. */ + if (optind < argc) + { + symarg = argv[optind]; + execarg = argv[optind]; + optind++; + } + + /* If the user hasn't already specified a PID or the name of a + core file, then a second optional argument is allowed. If + present, this argument should be interpreted as either a + PID or a core file, whichever works. */ + if (pidarg == NULL && corearg == NULL && optind < argc) + { + pid_or_core_arg = argv[optind]; + optind++; + } + + /* Any argument left on the command line is unexpected and + will be ignored. Inform the user. */ + if (optind < argc) + fprintf_unfiltered (gdb_stderr, _("\ +Excess command line arguments ignored. (%s%s)\n"), + argv[optind], + (optind == argc - 1) ? "" : " ..."); + } + /* Lookup gdbinit files. Note that the gdbinit file name may be overriden during file initialization, so get_init_files should be called after gdb_init. */ @@ -840,7 +843,7 @@ Can't attach to process and specify a core file at the same time.")); } if (ttyarg != NULL) - catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); + set_inferior_io_terminal (ttyarg); /* Error messages should no longer be distinguished with extra output. */ error_pre_print = NULL; diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c index d9703ee..5bb49fd 100644 --- a/gdb/mi/mi-cmd-env.c +++ b/gdb/mi/mi-cmd-env.c @@ -162,7 +162,7 @@ mi_cmd_env_path (char *command, char **argv, int argc) else { /* Otherwise, get current path to modify. */ - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); /* Can be null if path is not set. */ if (!env) @@ -173,9 +173,9 @@ mi_cmd_env_path (char *command, char **argv, int argc) for (i = argc - 1; i >= 0; --i) env_mod_path (argv[i], &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); + set_in_environ (current_inferior ()->environment, path_var_name, exec_path); xfree (exec_path); - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); ui_out_field_string (uiout, "path", env); } @@ -260,10 +260,17 @@ mi_cmd_inferior_tty_show (char *command, char **argv, int argc) void _initialize_mi_cmd_env (void) { + struct gdb_environ *environment; char *env; - /* We want original execution path to reset to, if desired later. */ - env = get_in_environ (inferior_environ, path_var_name); + /* We want original execution path to reset to, if desired later. + At this point, current inferior is not created, so cannot use + current_inferior ()->environment. Also, there's no obvious + place where this code can be moved suchs that it surely run + before any code possibly mangles original PATH. */ + environment = make_environ (); + init_environ (environment); + env = get_in_environ (environment, path_var_name); /* Can be null if path is not set. */ if (!env) diff --git a/gdb/solib.c b/gdb/solib.c index 21006d8..72c4212 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -227,14 +227,16 @@ solib_find (char *in_pathname, int *fd) /* If not found, next search the inferior's $PATH environment variable. */ if (found_file < 0 && gdb_sysroot_is_empty) - found_file = openp (get_in_environ (inferior_environ, "PATH"), + found_file = openp (get_in_environ (current_inferior ()->environment, + "PATH"), OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, &temp_pathname); /* If not found, next search the inferior's $LD_LIBRARY_PATH environment variable. */ if (found_file < 0 && gdb_sysroot_is_empty) - found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"), + found_file = openp (get_in_environ (current_inferior ()->environment, + "LD_LIBRARY_PATH"), OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, &temp_pathname); ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-14 15:09 ` Vladimir Prus @ 2010-01-14 15:49 ` Pedro Alves 2010-01-19 21:53 ` Vladimir Prus 0 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2010-01-14 15:49 UTC (permalink / raw) To: Vladimir Prus; +Cc: gdb-patches On Thursday 14 January 2010 15:09:17, Vladimir Prus wrote: > On Thursday 14 January 2010 16:37:42 Pedro Alves wrote: > > Better choices would be: set_inferior_tty_command/show_inferior_tty_command > > or set_inferior_tty/show_inferior_tty. > > Done. Also done for args function. Thanks. > > > @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) > > > { > > > discard_all_inferior_continuations (inf); > > > inferior_free_data (inf); > > > + xfree (inf->args); > > > > > + xfree (inf->argv); > > > > Hmm, I was going to say that this usually leaks argv[0..argc], and > > you should use freeargv, but, I now see that the only caller > > of set_inferior_args_vector is captured_main, and the > > argc,argv are presently a shallow copy of `main's arguments, so > > definitely not ok to free this as is. This definitely needs a > > comment in the description of inferior->argv, expanded from > > the comment that was in inferior_argv. > > I've added a comment. Thanks, but not correct yet... > @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) > { > discard_all_inferior_continuations (inf); > inferior_free_data (inf); > + xfree (inf->args); > + xfree (inf->argv); > + xfree (inf->terminal); > + free_environ (inf->environment); > xfree (inf->private); Maybe I confused you with saying "shallow" copy. This argv comes from a direct `argv' pointer copy: void set_inferior_args_vector (int argc, char **argv) { current_inferior ()->argc = argc; current_inferior ()->argv = argv; } This is only called from captured_main, like so: set_inferior_args_vector (argc - optind, &argv[optind]); So at best, you'd need to `xfree (&argv[-optind])', but even that would be broken. Say, let's ignore that offset. argv in that context is a pointer copy coming from: static int captured_main (void *data) { struct captured_main_args *context = data; int argc = context->argc; char **argv = context->argv; and this context->argv itself comes from: int main (int argc, char **argv) { struct captured_main_args args; memset (&args, 0, sizeof args); args.argc = argc; args.argv = argv; ^^^^^^^^^^^^^^^^ args.use_windows = 0; args.interpreter_p = INTERP_CONSOLE; return gdb_main (&args); } so, freeing that would be equivalent to: int main (int argc, char **argv) { free (argv); } which is not kosher (try it). You should _not_ free inferior->argv. Actually, I'll try it myself: > ./gdb -q --args /home/pedro/gdb/tests/threads --args foo bar (gdb) clone-inferior Added inferior 2. (gdb) inferior 1 [Switching to inferior 1 [process 0] (/home/pedro/gdb/tests/threads)] (gdb) inferior 2 [Switching to inferior 2 [process 0] (/home/pedro/gdb/tests/threads)] (gdb) remove-inferior 1 *** glibc detected *** ./gdb: munmap_chunk(): invalid pointer: 0x00007fff9d5b4fe8 *** ======= Backtrace: ========= /lib/libc.so.6(cfree+0x1b6)[0x7f7f0e86cd46] ./gdb(xfree+0x1c)[0x462f1e] : Cancelled (core dumped) And since you now made me try the patch... :-) >qr Warning: trailing whitespace in lines 230,238 of gdb/solib.c Warning: trailing whitespace in lines 664,673,683 of gdb/main.c Warning: trailing whitespace in line 266 of gdb/mi/mi-cmd-env.c Warning: trailing whitespace in lines 129,186,200,213,2653,2654,2655 of gdb/infcmd.c Refreshed patch per-inferior-args3.diff -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-14 15:49 ` Pedro Alves @ 2010-01-19 21:53 ` Vladimir Prus 2010-01-20 6:14 ` Pedro Alves 0 siblings, 1 reply; 9+ messages in thread From: Vladimir Prus @ 2010-01-19 21:53 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches [-- Attachment #1: Type: Text/Plain, Size: 1176 bytes --] On Thursday 14 January 2010 18:49:10 Pedro Alves wrote: > > @@ -87,6 +88,10 @@ free_inferior (struct inferior *inf) > > { > > discard_all_inferior_continuations (inf); > > inferior_free_data (inf); > > + xfree (inf->args); > > + xfree (inf->argv); > > + xfree (inf->terminal); > > + free_environ (inf->environment); > > xfree (inf->private); > > Maybe I confused you with saying "shallow" copy. This > argv comes from a direct `argv' pointer copy: ... > This is only called from captured_main, like so: > > set_inferior_args_vector (argc - optind, &argv[optind]); ... > so, freeing that would be equivalent to: > > int > main (int argc, char **argv) > { > free (argv); > } > > which is not kosher (try it). You should _not_ free inferior->argv. Ouch. Here's yet another revision. > >qr > Warning: trailing whitespace in lines 230,238 of gdb/solib.c > Warning: trailing whitespace in lines 664,673,683 of gdb/main.c > Warning: trailing whitespace in line 266 of gdb/mi/mi-cmd-env.c > Warning: trailing whitespace in lines 129,186,200,213,2653,2654,2655 of gdb/infcmd.c > Refreshed patch per-inferior-args3.diff Also fixed now. - Volodya [-- Attachment #2: per-inferior-args4.diff --] [-- Type: text/x-patch, Size: 21353 bytes --] commit 5ea1aab67573f59d22bedb6841d1fabdabed261c Author: Vladimir Prus <vladimir@codesourcery.com> Date: Mon Dec 21 15:28:03 2009 +0300 Per-inferior args and tty and environment. * infcmd.c (inferior_args): Rename to ... (inferior_args_scratch): ... this. (inferior_io_terminal): Rename to ... (inferior_io_terminal_scratch): ... this. (inferior_argc, inferior_argv): Remove. (set_inferior_io_terminal, get_inferior_io_terminal): Store inside current_inferior(). (set_inferior_tty_command, show_inferior_tty_command): New. (get_inferior_args, set_inferior_args): Store inside current_inferior(). (notice_args_set): Likewise and rename to... (set_args_command): ... this. (set_inferior_args_vector): Likewise. (notice_args_read): Rename to... (show_args_command): ...new. (tty_command): Remove. (run_command_1): Don't free old args, as they are freed by set_inferior_arg now. (run_no_args_command): Likewise. (inferior_environ): Remove. (run_command_1): Use environemnt of the current inferior. (environment_info, set_environment_command) (unset_environment_command, path_info, path_command): Likewise. (_initialize_infcmd): Adjust for function and variable renames. Do not init inferior_environ. * inferior.h (set_inferior_arg): Adjust prototype. (struct inferior): New fields args, argc, argv, terminal, environment. (inferior_environ): Remove declaration. * inferior.c (free_inferior): Free new fields. (add_inferior_silent): Initialize 'environment' field. * main.c (captured_main): Set arguments only after the initial inferior has been created. Set set_inferior_io_terminal, not tty_command. * mi/mi-main.c (mi_cmd_env_path): Use environment of the current inferior. (_initialize_mi_cmd_env): Adjust for disappearance of global inferior_environ. * solib.c (solib_find): Use environment of the current inferior. diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 21a2233..f99a4ae 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -126,20 +126,17 @@ void _initialize_infcmd (void); #define ERROR_NO_INFERIOR \ if (!target_has_execution) error (_("The program is not being run.")); -/* String containing arguments to give to the program, separated by spaces. - Empty string (pointer to '\0') means no args. */ +/* Scratch area where string containing arguments to give to the program will be + stored by 'set args'. As soon as anything is stored, notice_args_set will + move it into per-inferior storage. Arguments are separated by spaces. Empty + string (pointer to '\0') means no args. */ -static char *inferior_args; +static char *inferior_args_scratch; -/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero, - then we must compute INFERIOR_ARGS from this (via the target). */ +/* Scratch area where 'set inferior-tty' will store user-provided value. + We'll immediate copy it into per-inferior storage. */ -static int inferior_argc; -static char **inferior_argv; - -/* File name for default use for standard in/out in the inferior. */ - -static char *inferior_io_terminal; +static char *inferior_io_terminal_scratch; /* Pid of our debugged inferior, or 0 if no inferior now. Since various parts of infrun.c test this to see whether there is a program @@ -166,80 +163,97 @@ int stop_stack_dummy; int stopped_by_random_signal; -/* Environment to use for running inferior, - in format described in environ.h. */ - -struct gdb_environ *inferior_environ; \f /* Accessor routines. */ +/* Set the io terminal for the current inferior. Ownership of + TERMINAL_NAME is not transferred. */ + void set_inferior_io_terminal (const char *terminal_name) { - if (inferior_io_terminal) - xfree (inferior_io_terminal); - - if (!terminal_name) - inferior_io_terminal = NULL; - else - inferior_io_terminal = xstrdup (terminal_name); + xfree (current_inferior ()->terminal); + current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0; } const char * get_inferior_io_terminal (void) { - return inferior_io_terminal; + return current_inferior ()->terminal; +} + +static void +set_inferior_tty_command (char *args, int from_tty, + struct cmd_list_element *c) +{ + /* CLI has assigned the user-provided value to inferior_io_terminal_scratch. + Now route it to current inferior. */ + set_inferior_io_terminal (inferior_io_terminal_scratch); +} + +static void +show_inferior_tty_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + /* Note that we ignore the passed-in value in favor of computing it + directly. */ + fprintf_filtered (gdb_stdout, + _("argument list to give program being debugged when " + "it is started is %s"), + get_inferior_io_terminal ()); } char * get_inferior_args (void) { - if (inferior_argc != 0) + if (current_inferior ()->argc != 0) { - char *n, *old; + char *n; - n = construct_inferior_arguments (inferior_argc, inferior_argv); - old = set_inferior_args (n); - xfree (old); + n = construct_inferior_arguments (current_inferior ()->argc, + current_inferior ()->argv); + set_inferior_args (n); + xfree (n); } - if (inferior_args == NULL) - inferior_args = xstrdup (""); + if (current_inferior ()->args == NULL) + current_inferior ()->args = xstrdup (""); - return inferior_args; + return current_inferior ()->args; } -char * +/* Set the arguments for the current inferior. Ownership of + NEWARGS is not transferred. */ + +void set_inferior_args (char *newargs) { - char *saved_args = inferior_args; - - inferior_args = newargs; - inferior_argc = 0; - inferior_argv = 0; - - return saved_args; + xfree (current_inferior ()->args); + current_inferior ()->args = newargs ? xstrdup (newargs) : NULL; + current_inferior ()->argc = 0; + current_inferior ()->argv = 0; } void set_inferior_args_vector (int argc, char **argv) { - inferior_argc = argc; - inferior_argv = argv; + current_inferior ()->argc = argc; + current_inferior ()->argv = argv; } /* Notice when `set args' is run. */ static void -notice_args_set (char *args, int from_tty, struct cmd_list_element *c) +set_args_command (char *args, int from_tty, struct cmd_list_element *c) { - inferior_argc = 0; - inferior_argv = 0; + /* CLI has assigned the user-provided value to inferior_args_scratch. + Now route it to current inferior. */ + set_inferior_args (inferior_args_scratch); } /* Notice when `show args' is run. */ static void -notice_args_read (struct ui_file *file, int from_tty, - struct cmd_list_element *c, const char *value) +show_args_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) { /* Note that we ignore the passed-in value in favor of computing it directly. */ @@ -369,15 +383,6 @@ strip_bg_char (char **args) return 0; } -void -tty_command (char *file, int from_tty) -{ - if (file == 0) - error_no_arg (_("terminal name for running target process")); - - set_inferior_io_terminal (file); -} - /* Common actions to take after creating any sort of inferior, by any means (running, attaching, connecting, et cetera). The target should be stopped. */ @@ -536,10 +541,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* If there were other args, beside '&', process them. */ if (args) - { - char *old_args = set_inferior_args (xstrdup (args)); - xfree (old_args); - } + set_inferior_args (args); } if (from_tty) @@ -559,7 +561,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) /* We call get_inferior_args() because we might need to compute the value now. */ target_create_inferior (exec_file, get_inferior_args (), - environ_vector (inferior_environ), from_tty); + environ_vector (current_inferior ()->environment), from_tty); /* We're starting off a new process. When we get out of here, in non-stop mode, finish the state of all threads of that process, @@ -594,8 +596,7 @@ run_command (char *args, int from_tty) static void run_no_args_command (char *args, int from_tty) { - char *old_args = set_inferior_args (xstrdup ("")); - xfree (old_args); + set_inferior_args (""); } \f @@ -1699,7 +1700,7 @@ environment_info (char *var, int from_tty) { if (var) { - char *val = get_in_environ (inferior_environ, var); + char *val = get_in_environ (current_inferior ()->environment, var); if (val) { puts_filtered (var); @@ -1716,7 +1717,7 @@ environment_info (char *var, int from_tty) } else { - char **vector = environ_vector (inferior_environ); + char **vector = environ_vector (current_inferior ()->environment); while (*vector) { puts_filtered (*vector++); @@ -1781,10 +1782,10 @@ set_environment_command (char *arg, int from_tty) printf_filtered (_("\ Setting environment variable \"%s\" to null value.\n"), var); - set_in_environ (inferior_environ, var, ""); + set_in_environ (current_inferior ()->environment, var, ""); } else - set_in_environ (inferior_environ, var, val); + set_in_environ (current_inferior ()->environment, var, val); xfree (var); } @@ -1797,12 +1798,12 @@ unset_environment_command (char *var, int from_tty) Ask for confirmation if reading from the terminal. */ if (!from_tty || query (_("Delete all environment variables? "))) { - free_environ (inferior_environ); - inferior_environ = make_environ (); + free_environ (current_inferior ()->environment); + current_inferior ()->environment = make_environ (); } } else - unset_in_environ (inferior_environ, var); + unset_in_environ (current_inferior ()->environment, var); } /* Handle the execution path (PATH variable) */ @@ -1813,7 +1814,7 @@ static void path_info (char *args, int from_tty) { puts_filtered ("Executable and object file path: "); - puts_filtered (get_in_environ (inferior_environ, path_var_name)); + puts_filtered (get_in_environ (current_inferior ()->environment, path_var_name)); puts_filtered ("\n"); } @@ -1825,13 +1826,13 @@ path_command (char *dirname, int from_tty) char *exec_path; char *env; dont_repeat (); - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); /* Can be null if path is not set */ if (!env) env = ""; exec_path = xstrdup (env); mod_path (dirname, &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); + set_in_environ (current_inferior ()->environment, path_var_name, exec_path); xfree (exec_path); if (from_tty) path_info ((char *) NULL, from_tty); @@ -2646,19 +2647,22 @@ _initialize_infcmd (void) /* add the filename of the terminal connected to inferior I/O */ add_setshow_filename_cmd ("inferior-tty", class_run, - &inferior_io_terminal, _("\ + &inferior_io_terminal_scratch, _("\ Set terminal for future runs of program being debugged."), _("\ Show terminal for future runs of program being debugged."), _("\ -Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist); +Usage: set inferior-tty /dev/pts/1"), + set_inferior_tty_command, + show_inferior_tty_command, + &setlist, &showlist); add_com_alias ("tty", "set inferior-tty", class_alias, 0); add_setshow_optional_filename_cmd ("args", class_run, - &inferior_args, _("\ + &inferior_args_scratch, _("\ Set argument list to give program being debugged when it is started."), _("\ Show argument list to give program being debugged when it is started."), _("\ Follow this command with any number of args, to be passed to the program."), - notice_args_set, - notice_args_read, + set_args_command, + show_args_command, &setlist, &showlist); c = add_cmd ("environment", no_class, environment_info, _("\ @@ -2855,7 +2859,4 @@ Register name as argument means describe only that register.")); add_info ("vector", vector_info, _("Print the status of the vector unit\n")); - - inferior_environ = make_environ (); - init_environ (inferior_environ); } diff --git a/gdb/inferior.c b/gdb/inferior.c index d27a3e3..0667bfa 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -29,6 +29,7 @@ #include "gdbthread.h" #include "gdbcore.h" #include "symfile.h" +#include "environ.h" void _initialize_inferiors (void); @@ -87,6 +88,9 @@ free_inferior (struct inferior *inf) { discard_all_inferior_continuations (inf); inferior_free_data (inf); + xfree (inf->args); + xfree (inf->terminal); + free_environ (inf->environment); xfree (inf->private); xfree (inf); } @@ -124,6 +128,9 @@ add_inferior_silent (int pid) inf->next = inferior_list; inferior_list = inf; + inf->environment = make_environ (); + init_environ (inf->environment); + inferior_alloc_data (inf); if (pid != 0) diff --git a/gdb/inferior.h b/gdb/inferior.h index 9798ef1..e557d6c 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -131,8 +131,6 @@ extern int sync_execution; /* Inferior environment. */ -extern struct gdb_environ *inferior_environ; - extern void clear_proceed_status (void); extern void proceed (CORE_ADDR, enum target_signal, int); @@ -253,15 +251,13 @@ void set_step_info (struct frame_info *frame, struct symtab_and_line sal); /* From infcmd.c */ -extern void tty_command (char *, int); - extern void post_create_inferior (struct target_ops *, int); extern void attach_command (char *, int); extern char *get_inferior_args (void); -extern char *set_inferior_args (char *); +extern void set_inferior_args (char *); extern void set_inferior_args_vector (int, char **); @@ -427,6 +423,25 @@ struct inferior /* The program space bound to this inferior. */ struct program_space *pspace; + /* The arguments string to use when running. */ + char *args; + + /* The size of elements in argv. */ + int argc; + + /* The vector version of arguments. If ARGC is nonzero, + then we must compute ARGS from this (via the target). + This is always coming from main's argv and therefore + should never be freed. */ + char **argv; + + /* The name of terminal device to use for I/O. */ + char *terminal; + + /* Environment to use for running inferior, + in format described in environ.h. */ + struct gdb_environ *environment; + /* See the definition of stop_kind above. */ enum stop_kind stop_soon; diff --git a/gdb/main.c b/gdb/main.c index 0cc0f75..e261348 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -631,54 +631,6 @@ extern int gdbtk_test (char *); use_windows = 0; } - if (set_args) - { - /* The remaining options are the command-line options for the - inferior. The first one is the sym/exec file, and the rest - are arguments. */ - if (optind >= argc) - { - fprintf_unfiltered (gdb_stderr, - _("%s: `--args' specified but no program specified\n"), - argv[0]); - exit (1); - } - symarg = argv[optind]; - execarg = argv[optind]; - ++optind; - set_inferior_args_vector (argc - optind, &argv[optind]); - } - else - { - /* OK, that's all the options. */ - - /* The first argument, if specified, is the name of the - executable. */ - if (optind < argc) - { - symarg = argv[optind]; - execarg = argv[optind]; - optind++; - } - - /* If the user hasn't already specified a PID or the name of a - core file, then a second optional argument is allowed. If - present, this argument should be interpreted as either a - PID or a core file, whichever works. */ - if (pidarg == NULL && corearg == NULL && optind < argc) - { - pid_or_core_arg = argv[optind]; - optind++; - } - - /* Any argument left on the command line is unexpected and - will be ignored. Inform the user. */ - if (optind < argc) - fprintf_unfiltered (gdb_stderr, _("\ -Excess command line arguments ignored. (%s%s)\n"), - argv[optind], - (optind == argc - 1) ? "" : " ..."); - } if (batch) quiet = 1; } @@ -687,6 +639,57 @@ Excess command line arguments ignored. (%s%s)\n"), control of the console via the deprecated_init_ui_hook (). */ gdb_init (argv[0]); + /* Now that gdb_init has created the initial inferior, we're in position + to set args for that inferior. */ + if (set_args) + { + /* The remaining options are the command-line options for the + inferior. The first one is the sym/exec file, and the rest + are arguments. */ + if (optind >= argc) + { + fprintf_unfiltered (gdb_stderr, + _("%s: `--args' specified but no program specified\n"), + argv[0]); + exit (1); + } + symarg = argv[optind]; + execarg = argv[optind]; + ++optind; + set_inferior_args_vector (argc - optind, &argv[optind]); + } + else + { + /* OK, that's all the options. */ + + /* The first argument, if specified, is the name of the + executable. */ + if (optind < argc) + { + symarg = argv[optind]; + execarg = argv[optind]; + optind++; + } + + /* If the user hasn't already specified a PID or the name of a + core file, then a second optional argument is allowed. If + present, this argument should be interpreted as either a + PID or a core file, whichever works. */ + if (pidarg == NULL && corearg == NULL && optind < argc) + { + pid_or_core_arg = argv[optind]; + optind++; + } + + /* Any argument left on the command line is unexpected and + will be ignored. Inform the user. */ + if (optind < argc) + fprintf_unfiltered (gdb_stderr, _("\ +Excess command line arguments ignored. (%s%s)\n"), + argv[optind], + (optind == argc - 1) ? "" : " ..."); + } + /* Lookup gdbinit files. Note that the gdbinit file name may be overriden during file initialization, so get_init_files should be called after gdb_init. */ @@ -840,7 +843,7 @@ Can't attach to process and specify a core file at the same time.")); } if (ttyarg != NULL) - catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); + set_inferior_io_terminal (ttyarg); /* Error messages should no longer be distinguished with extra output. */ error_pre_print = NULL; diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c index d9703ee..cdd25f2 100644 --- a/gdb/mi/mi-cmd-env.c +++ b/gdb/mi/mi-cmd-env.c @@ -162,7 +162,7 @@ mi_cmd_env_path (char *command, char **argv, int argc) else { /* Otherwise, get current path to modify. */ - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); /* Can be null if path is not set. */ if (!env) @@ -173,9 +173,9 @@ mi_cmd_env_path (char *command, char **argv, int argc) for (i = argc - 1; i >= 0; --i) env_mod_path (argv[i], &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); + set_in_environ (current_inferior ()->environment, path_var_name, exec_path); xfree (exec_path); - env = get_in_environ (inferior_environ, path_var_name); + env = get_in_environ (current_inferior ()->environment, path_var_name); ui_out_field_string (uiout, "path", env); } @@ -260,10 +260,17 @@ mi_cmd_inferior_tty_show (char *command, char **argv, int argc) void _initialize_mi_cmd_env (void) { + struct gdb_environ *environment; char *env; - /* We want original execution path to reset to, if desired later. */ - env = get_in_environ (inferior_environ, path_var_name); + /* We want original execution path to reset to, if desired later. + At this point, current inferior is not created, so cannot use + current_inferior ()->environment. Also, there's no obvious + place where this code can be moved suchs that it surely run + before any code possibly mangles original PATH. */ + environment = make_environ (); + init_environ (environment); + env = get_in_environ (environment, path_var_name); /* Can be null if path is not set. */ if (!env) diff --git a/gdb/solib.c b/gdb/solib.c index 21006d8..842b27c 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -227,14 +227,16 @@ solib_find (char *in_pathname, int *fd) /* If not found, next search the inferior's $PATH environment variable. */ if (found_file < 0 && gdb_sysroot_is_empty) - found_file = openp (get_in_environ (inferior_environ, "PATH"), + found_file = openp (get_in_environ (current_inferior ()->environment, + "PATH"), OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, &temp_pathname); /* If not found, next search the inferior's $LD_LIBRARY_PATH environment variable. */ if (found_file < 0 && gdb_sysroot_is_empty) - found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"), + found_file = openp (get_in_environ (current_inferior ()->environment, + "LD_LIBRARY_PATH"), OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, &temp_pathname); ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-19 21:53 ` Vladimir Prus @ 2010-01-20 6:14 ` Pedro Alves 2010-01-20 14:23 ` Vladimir Prus 0 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2010-01-20 6:14 UTC (permalink / raw) To: Vladimir Prus; +Cc: gdb-patches On Tuesday 19 January 2010 21:53:23, Vladimir Prus wrote: > Per-inferior args and tty and environment. > > * infcmd.c (inferior_args): Rename to ... > (inferior_args_scratch): ... this. > (inferior_io_terminal): Rename to ... > (inferior_io_terminal_scratch): ... this. > (inferior_argc, inferior_argv): Remove. > (set_inferior_io_terminal, get_inferior_io_terminal): Store > inside current_inferior(). > (set_inferior_tty_command, show_inferior_tty_command): New. > (get_inferior_args, set_inferior_args): Store inside > current_inferior(). > (notice_args_set): Likewise and rename to... > (set_args_command): ... this. > (set_inferior_args_vector): Likewise. > (notice_args_read): Rename to... > (show_args_command): ...new. > (tty_command): Remove. > (run_command_1): Don't free old args, as they are freed by > set_inferior_arg now. > (run_no_args_command): Likewise. > (inferior_environ): Remove. > (run_command_1): Use environemnt of the current inferior. Typo: "environemnt" > (environment_info, set_environment_command) > (unset_environment_command, path_info, path_command): Likewise. > (_initialize_infcmd): Adjust for function and variable renames. > Do not init inferior_environ. > * inferior.h (set_inferior_arg): Adjust prototype. > (struct inferior): New fields args, argc, argv, terminal, environment. > (inferior_environ): Remove declaration. > * inferior.c (free_inferior): Free new fields. > (add_inferior_silent): Initialize 'environment' field. > * main.c (captured_main): Set arguments only after the initial > inferior has been created. Set set_inferior_io_terminal, > not tty_command. > * mi/mi-main.c (mi_cmd_env_path): Use environment of the current > inferior. > (_initialize_mi_cmd_env): Adjust for disappearance of global > inferior_environ. > * solib.c (solib_find): Use environment of the current inferior. This version is OK. Thanks. -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Per-inferior program arguments and io terminal 2010-01-20 6:14 ` Pedro Alves @ 2010-01-20 14:23 ` Vladimir Prus 0 siblings, 0 replies; 9+ messages in thread From: Vladimir Prus @ 2010-01-20 14:23 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On Wednesday 20 January 2010 09:14:26 Pedro Alves wrote: > On Tuesday 19 January 2010 21:53:23, Vladimir Prus wrote: > > > Per-inferior args and tty and environment. > > > > * infcmd.c (inferior_args): Rename to ... > > (inferior_args_scratch): ... this. > > (inferior_io_terminal): Rename to ... > > (inferior_io_terminal_scratch): ... this. > > (inferior_argc, inferior_argv): Remove. > > (set_inferior_io_terminal, get_inferior_io_terminal): Store > > inside current_inferior(). > > (set_inferior_tty_command, show_inferior_tty_command): New. > > (get_inferior_args, set_inferior_args): Store inside > > current_inferior(). > > (notice_args_set): Likewise and rename to... > > (set_args_command): ... this. > > (set_inferior_args_vector): Likewise. > > (notice_args_read): Rename to... > > (show_args_command): ...new. > > (tty_command): Remove. > > (run_command_1): Don't free old args, as they are freed by > > set_inferior_arg now. > > (run_no_args_command): Likewise. > > (inferior_environ): Remove. > > (run_command_1): Use environemnt of the current inferior. > > Typo: "environemnt" > > > (environment_info, set_environment_command) > > (unset_environment_command, path_info, path_command): Likewise. > > (_initialize_infcmd): Adjust for function and variable renames. > > Do not init inferior_environ. > > * inferior.h (set_inferior_arg): Adjust prototype. > > (struct inferior): New fields args, argc, argv, terminal, environment. > > (inferior_environ): Remove declaration. > > * inferior.c (free_inferior): Free new fields. > > (add_inferior_silent): Initialize 'environment' field. > > * main.c (captured_main): Set arguments only after the initial > > inferior has been created. Set set_inferior_io_terminal, > > not tty_command. > > * mi/mi-main.c (mi_cmd_env_path): Use environment of the current > > inferior. > > (_initialize_mi_cmd_env): Adjust for disappearance of global > > inferior_environ. > > * solib.c (solib_find): Use environment of the current inferior. > > This version is OK. Thanks. Thanks, checked in. - Volodya ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-01-20 14:23 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-01-13 12:44 Per-inferior program arguments and io terminal Vladimir Prus 2010-01-13 15:49 ` Pedro Alves 2010-01-14 9:27 ` Vladimir Prus 2010-01-14 13:38 ` Pedro Alves 2010-01-14 15:09 ` Vladimir Prus 2010-01-14 15:49 ` Pedro Alves 2010-01-19 21:53 ` Vladimir Prus 2010-01-20 6:14 ` Pedro Alves 2010-01-20 14:23 ` Vladimir Prus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox