* PATCH: gdb --args
@ 2001-10-10 15:28 Tom Tromey
2001-10-11 1:02 ` Eli Zaretskii
2001-10-11 8:32 ` Andrew Cagney
0 siblings, 2 replies; 8+ messages in thread
From: Tom Tromey @ 2001-10-10 15:28 UTC (permalink / raw)
To: gdb-patches
This patch implements `gdb --args'. `--args' stops command-line
processing, and everything after it is used as the name of the
executable and its arguments. Roughly:
gdb --args program foo bar
is equivalent to
gdb program
set args foo bar
Internally the code works by storing the command-line arguments as a
vector, and then lazily computing the actual argument string the first
time it is requested. I took this approach because it allows for the
case where the target isn't known until relatively late -- stringizing
the argument vector is target-specific.
I didn't implement the new target method for every target. For
instance, I have no way to test on Windows, and discussion on the list
indicated that I probably couldn't reliably do this work without being
able to test it. Fixing other targets is easy, though. Writing the
stringizing function is straightforward for someone familiar with the
target.
I did set the target vector slot for targets I have no way of
testing. Perhaps that is wrong. However, I did it for any target
which uses fork-inferior, which seemed like a correct approach.
Many targets don't handle command-line options at all.
With this patch, if you use `gdb --args ...' and then try to see the
command-line arguments (eg via `show args'), you'll get an error
indicating that the target doesn't support command-line arguments. I
tested this by temporarily hacking the unix-native target to not
initialize the new field of the target vector.
I had to add a `pre_show_hook' to `struct cmd_list_element'. This
hook is what enables us to lazily compute the arguments. I didn't see
another way to do this. I'm a bit dubious about this part of the
patch.
I've been using this patch for a while now without problems. It
builds fine on x86 Red Hat Linux 6.2 and it passes the test suite. In
practice I've found it to be every bit as useful as I thought it would
be. So far I've mostly used it to make my life easier when doing
cut-and-paste, but soon I'm going to hack gcc so that I can start gdb
directly when it launches the subprocess I'm interested in.
Ok to commit?
If it is ok, what is the protocol for closing PRs? For gcj I just
assign them to myself and then mark them as closed. Is this ok for
gdb too?
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
Fix for PR gdb/209, PR gdb/156:
* procfs.c (procfs_construct_inferior_arguments): New function.
(init_procfs_ops): Use it.
* m3-nat.c (m3_construct_inferior_arguments): New function.
(init_m3_ops): Use it.
* linux-thread.c (linuxthreads_construct_inferior_arguments): New
function.
(init_linuxthreads_ops): Use it.
* lin-lwp.c (lin_lwp_construct_inferior_arguments): New function.
(init_lin_lwp_ops): Use it.
* gnu-nat.c (init_gnu_ops): Set to_construct_inferior_arguments.
(gnu_construct_inferior_arguments): New function.
* cli/cli-decode.h (cmd_list_element): Added pre_show_hook.
Typo fix.
* cli/cli-setshow.c (do_setshow_command): Call the pre_show_hook.
* infcmd.c (_initialize_infcmd): Set sfunc on `set args' command.
(inferior_argc, inferior_argv): New globals.
(notice_args_set): New function.
(set_inferior_args): Clear inferior_argc and inferior_argv.
(set_inferior_args_vector): New function.
(get_inferior_args): Handle inferior argument vector.
(run_command): Use get_inferior_args().
(notice_args_read): New function.
(_initialize_infcmd): Don't call set_inferior_args.
* command.h: Typo fix.
(cmd_list_element): Added pre_show_hook.
* main.c (captured_main): Added --args option.
(print_gdb_help): Document --args.
* inferior.h (construct_inferior_arguments): Declare.
* fork-child.c (construct_inferior_arguments): New function.
* inftarg.c (child_construct_inferior_arguments): New function.
(init_child_ops): Use it.
* exec.c (init_exec_ops): Initialize
to_construct_inferior_arguments.
* corelow.c (init_core_ops): Initialize
to_construct_inferior_arguments.
* target.c (find_default_construct_inferior_arguments): New
function.
* target.h (target_ops): Added to_construct_inferior_arguments.
(target_construct_inferior_arguments): New macro.
(find_default_construct_inferior_arguments): Declare.
Index: command.h
===================================================================
RCS file: /cvs/src/src/gdb/command.h,v
retrieving revision 1.19
diff -u -r1.19 command.h
--- command.h 2001/09/30 16:16:16 1.19
+++ command.h 2001/10/10 21:57:20
@@ -134,7 +134,7 @@
/* If type is not_set_cmd, call it like this: */
void (*cfunc) (char *args, int from_tty);
- /* If type is cmd_set or show_cmd, first set the variables, and
+ /* If type is set_cmd or show_cmd, first set the variables, and
then call this. */
void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c);
}
@@ -171,6 +171,10 @@
/* if this command is deprecated, this is the replacement name */
char *replacement;
+
+ /* If this command represents a show command, then this function
+ is called before the variable's value is examined. */
+ void (*pre_show_hook) (struct cmd_list_element *c);
/* Hook for another command to be executed before this command. */
struct cmd_list_element *hook_pre;
Index: corelow.c
===================================================================
RCS file: /cvs/src/src/gdb/corelow.c,v
retrieving revision 1.17
diff -u -r1.17 corelow.c
--- corelow.c 2001/05/15 00:03:36 1.17
+++ corelow.c 2001/10/10 21:57:21
@@ -511,6 +511,7 @@
core_ops.to_insert_breakpoint = ignore;
core_ops.to_remove_breakpoint = ignore;
core_ops.to_create_inferior = find_default_create_inferior;
+ core_ops.to_construct_inferior_arguments = find_default_construct_inferior_arguments;
core_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
core_ops.to_thread_alive = core_file_thread_alive;
core_ops.to_stratum = core_stratum;
Index: exec.c
===================================================================
RCS file: /cvs/src/src/gdb/exec.c,v
retrieving revision 1.13
diff -u -r1.13 exec.c
--- exec.c 2001/03/22 23:58:37 1.13
+++ exec.c 2001/10/10 21:57:21
@@ -706,6 +706,7 @@
exec_ops.to_insert_breakpoint = ignore;
exec_ops.to_remove_breakpoint = ignore;
exec_ops.to_create_inferior = find_default_create_inferior;
+ exec_ops.to_construct_inferior_arguments = find_default_construct_inferior_arguments;
exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
exec_ops.to_stratum = file_stratum;
exec_ops.to_has_memory = 1;
Index: fork-child.c
===================================================================
RCS file: /cvs/src/src/gdb/fork-child.c,v
retrieving revision 1.13
diff -u -r1.13 fork-child.c
--- fork-child.c 2001/05/04 04:15:24 1.13
+++ fork-child.c 2001/10/10 21:57:22
@@ -570,3 +570,74 @@
#endif /* STARTUP_INFERIOR */
stop_soon_quietly = 0;
}
+
+/* Compute command-line string given argument vector. This does the
+ same shell processing as fork_inferior. */
+
+char *
+construct_inferior_arguments (int argc, char **argv)
+{
+ char *result;
+
+ if (STARTUP_WITH_SHELL)
+ {
+ /* This holds all the characters considered special to the
+ typical Unix shells. We include `^' because the SunOS
+ /bin/sh treats it as a synonym for `|'. */
+ char *special = "\"!#$&*()\\|[]{}<>?'\"`~^; \t\n";
+ int i;
+ int length = 0;
+ char *out, *cp;
+
+ /* We over-compute the size. It shouldn't matter. */
+ for (i = 0; i < argc; ++i)
+ length += 2 * strlen (argv[i]) + 1;
+
+ result = (char *) xmalloc (length);
+ out = result;
+
+ for (i = 0; i < argc; ++i)
+ {
+ if (i > 0)
+ *out++ = ' ';
+
+ for (cp = argv[i]; *cp; ++cp)
+ {
+ if (strchr (special, *cp) != NULL)
+ *out++ = '\\';
+ *out++ = *cp;
+ }
+ }
+ *out = '\0';
+ }
+ else
+ {
+ /* In this case we can't handle arguments that contain spaces,
+ tabs, or newlines -- see breakup_args(). */
+ int i;
+ int length = 0;
+
+ for (i = 0; i < argc; ++i)
+ {
+ char *cp = strchr (argv[i], ' ');
+ if (cp == NULL)
+ cp = strchr (argv[i], '\t');
+ if (cp == NULL)
+ cp = strchr (argv[i], '\n');
+ if (cp != NULL)
+ error ("can't handle command-line argument containing whitespace");
+ length += strlen (argv[i]) + 1;
+ }
+
+ result = (char *) xmalloc (length);
+ result[0] = '\0';
+ for (i = 0; i < argc; ++i)
+ {
+ if (i > 0)
+ strcat (result, " ");
+ strcat (result, argv[i]);
+ }
+ }
+
+ return result;
+}
Index: gnu-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-nat.c,v
retrieving revision 1.16
diff -u -r1.16 gnu-nat.c
--- gnu-nat.c 2001/05/24 20:05:07 1.16
+++ gnu-nat.c 2001/10/10 21:57:24
@@ -2092,6 +2092,12 @@
proceed ((CORE_ADDR) -1, 0, 0);
}
+static char *
+gnu_construct_inferior_arguments (int argc, char **argv)
+{
+ return construct_inferior_arguments (argc, argv);
+}
+
/* Mark our target-struct as eligible for stray "run" and "attach"
commands. */
static int
@@ -2536,6 +2542,8 @@
gnu_ops.to_load = 0; /* to_load */
gnu_ops.to_lookup_symbol = 0; /* to_lookup_symbol */
gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */
+ gnu_ops.to_construct_inferior_arguments = gnu_construct_inferior_arguments;
+ /* to_construct_inferior_arguments */
gnu_ops.to_post_startup_inferior = NULL; /* to_post_startup_inferior */
/* to_acknowledge_created_inferior */
gnu_ops.to_acknowledge_created_inferior = NULL;
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.31
diff -u -r1.31 infcmd.c
--- infcmd.c 2001/10/01 18:11:19 1.31
+++ infcmd.c 2001/10/10 21:57:26
@@ -123,6 +123,12 @@
static char *inferior_args;
+/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero,
+ then we must compute INFERIOR_ARGS from this (via the target). */
+
+static int inferior_argc;
+static char **inferior_argv;
+
/* File name for default use for standard in/out in the inferior. */
char *inferior_io_terminal;
@@ -199,6 +205,19 @@
char *
get_inferior_args (void)
{
+ if (inferior_argc != 0)
+ {
+ char *n, *old;
+
+ n = find_default_construct_inferior_arguments (inferior_argc,
+ inferior_argv);
+ old = set_inferior_args (n);
+ xfree (old);
+ }
+
+ if (inferior_args == NULL)
+ inferior_args = xstrdup ("");
+
return inferior_args;
}
@@ -208,10 +227,35 @@
char *saved_args = inferior_args;
inferior_args = newargs;
+ inferior_argc = 0;
+ inferior_argv = 0;
return saved_args;
}
+void
+set_inferior_args_vector (int argc, char **argv)
+{
+ inferior_argc = argc;
+ 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;
+}
+
+/* Notice when `show args' is run. */
+static void
+notice_args_read (struct cmd_list_element *c)
+{
+ /* Might compute the value. */
+ get_inferior_args ();
+}
+
/* This function detects whether or not a '&' character (indicating
background execution) has been added as *the last* of the arguments ARGS
of a command. If it has, it removes it and returns 1. Otherwise it
@@ -331,7 +375,9 @@
if (exec_file)
ui_out_field_string (uiout, "execfile", exec_file);
ui_out_spaces (uiout, 1);
- ui_out_field_string (uiout, "infargs", inferior_args);
+ /* We call get_inferior_args() because we might need to compute
+ the value now. */
+ ui_out_field_string (uiout, "infargs", get_inferior_args ());
ui_out_text (uiout, "\n");
ui_out_flush (uiout);
#else
@@ -339,13 +385,17 @@
if (exec_file)
puts_filtered (exec_file);
puts_filtered (" ");
- puts_filtered (inferior_args);
+ /* We call get_inferior_args() because we might need to compute
+ the value now. */
+ puts_filtered (get_inferior_args ());
puts_filtered ("\n");
gdb_flush (gdb_stdout);
#endif
}
- target_create_inferior (exec_file, inferior_args,
+ /* 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));
}
@@ -1792,8 +1842,10 @@
"Set argument list to give program being debugged when it is started.\n\
Follow this command with any number of args, to be passed to the program.",
&setlist);
- add_show_from_set (c, &showlist);
c->completer = filename_completer;
+ c->function.sfunc = notice_args_set;
+ c = add_show_from_set (c, &showlist);
+ c->pre_show_hook = notice_args_read;
c = add_cmd
("environment", no_class, environment_info,
@@ -1959,7 +2011,6 @@
add_info ("float", float_info,
"Print the status of the floating point unit\n");
- set_inferior_args (xstrdup ("")); /* Initially no args */
inferior_environ = make_environ ();
init_environ (inferior_environ);
}
Index: inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.23
diff -u -r1.23 inferior.h
--- inferior.h 2001/05/15 00:03:36 1.23
+++ inferior.h 2001/10/10 21:57:26
@@ -270,6 +270,8 @@
extern void startup_inferior (int);
+extern char *construct_inferior_arguments (int, char **);
+
/* From inflow.c */
extern void new_tty_prefork (char *);
@@ -306,6 +308,8 @@
extern char *get_inferior_args (void);
extern char *set_inferior_args (char *);
+
+extern void set_inferior_args_vector (int, char **);
/* Last signal that the inferior received (why it stopped). */
Index: inftarg.c
===================================================================
RCS file: /cvs/src/src/gdb/inftarg.c,v
retrieving revision 1.7
diff -u -r1.7 inftarg.c
--- inftarg.c 2001/05/04 04:15:25 1.7
+++ inftarg.c 2001/10/10 21:57:27
@@ -80,6 +80,8 @@
static void child_create_inferior (char *, char *, char **);
+static char *child_construct_inferior_arguments (int, char **);
+
static void child_mourn_inferior (void);
static int child_can_run (void);
@@ -473,6 +475,21 @@
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}
+/* Given a vector of command-line arguments, return a newly allocated
+ string which, when passed to the create_inferior function, will be
+ parsed to yield the same vector. Return NULL if this target does
+ not support command-line arguments. This function should call
+ error() if the argument vector is not representable for this
+ target.
+ ARGC is the number of elements in the vector.
+ ARGV is an array of strings, one per argument. */
+
+static char *
+child_construct_inferior_arguments (int argc, char **argv)
+{
+ return construct_inferior_arguments (argc, argv);
+}
+
#if !defined(CHILD_POST_STARTUP_INFERIOR)
void
child_post_startup_inferior (ptid_t ptid)
@@ -777,6 +794,7 @@
child_ops.to_terminal_info = child_terminal_info;
child_ops.to_kill = kill_inferior;
child_ops.to_create_inferior = child_create_inferior;
+ child_ops.to_construct_inferior_arguments = child_construct_inferior_arguments;
child_ops.to_post_startup_inferior = child_post_startup_inferior;
child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior;
Index: lin-lwp.c
===================================================================
RCS file: /cvs/src/src/gdb/lin-lwp.c,v
retrieving revision 1.29
diff -u -r1.29 lin-lwp.c
--- lin-lwp.c 2001/07/13 12:49:31 1.29
+++ lin-lwp.c 2001/10/10 21:57:28
@@ -1228,6 +1228,12 @@
child_ops.to_create_inferior (exec_file, allargs, env);
}
+static char *
+lin_lwp_construct_inferior_arguments (int argc, char **argv)
+{
+ return child_ops.to_construct_inferior_arguments (argc, argv);
+}
+
static void
lin_lwp_mourn_inferior (void)
{
@@ -1331,6 +1337,7 @@
lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory;
lin_lwp_ops.to_kill = lin_lwp_kill;
lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior;
+ lin_lwp_ops.to_construct_inferior_arguments = lin_lwp_construct_inferior_arguments;
lin_lwp_ops.to_mourn_inferior = lin_lwp_mourn_inferior;
lin_lwp_ops.to_thread_alive = lin_lwp_thread_alive;
lin_lwp_ops.to_pid_to_str = lin_lwp_pid_to_str;
Index: linux-thread.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread.c,v
retrieving revision 1.15
diff -u -r1.15 linux-thread.c
--- linux-thread.c 2001/06/06 16:31:32 1.15
+++ linux-thread.c 2001/10/10 21:57:29
@@ -1568,6 +1568,12 @@
child_ops.to_create_inferior (exec_file, allargs, env);
}
+static char *
+linuxthreads_construct_inferior_arguments (int argc, char **argv)
+{
+ return child_ops.to_construct_inferior_arguments (argc, argv);
+}
+
void
linuxthreads_discard_global_state (void)
{
@@ -1716,6 +1722,8 @@
linuxthreads_ops.to_insert_breakpoint = linuxthreads_insert_breakpoint;
linuxthreads_ops.to_remove_breakpoint = linuxthreads_remove_breakpoint;
linuxthreads_ops.to_create_inferior = linuxthreads_create_inferior;
+ linuxthreads_ops.to_construct_inferior_arguments
+ = linuxthreads_construct_inferior_arguments;
linuxthreads_ops.to_mourn_inferior = linuxthreads_mourn_inferior;
linuxthreads_ops.to_thread_alive = linuxthreads_thread_alive;
linuxthreads_ops.to_pid_to_str = linuxthreads_pid_to_str;
Index: m3-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/m3-nat.c,v
retrieving revision 1.14
diff -u -r1.14 m3-nat.c
--- m3-nat.c 2001/06/06 16:31:32 1.14
+++ m3-nat.c 2001/10/10 21:57:32
@@ -3866,6 +3866,12 @@
proceed ((CORE_ADDR) -1, 0, 0);
}
+static char *
+m3_construct_inferior_arguments (int argc, char **argv)
+{
+ return construct_inferior_arguments (argc, argv);
+}
+
/* Mark our target-struct as eligible for stray "run" and "attach"
commands. */
static int
@@ -4478,6 +4484,7 @@
m3_ops.to_terminal_info = child_terminal_info;
m3_ops.to_kill = m3_kill_inferior;
m3_ops.to_create_inferior = m3_create_inferior;
+ m3_ops.to_construct_inferior_arguments = m3_construct_inferior_arguments;
m3_ops.to_mourn_inferior = m3_mourn_inferior;
m3_ops.to_can_run = m3_can_run;
m3_ops.to_stop = m3_stop;
Index: main.c
===================================================================
RCS file: /cvs/src/src/gdb/main.c,v
retrieving revision 1.13
diff -u -r1.13 main.c
--- main.c 2001/10/04 15:04:27 1.13
+++ main.c 2001/10/10 21:57:33
@@ -124,6 +124,7 @@
int count;
static int quiet = 0;
static int batch = 0;
+ static int set_args = 0;
/* Pointers to various arguments from command line. */
char *symarg = NULL;
@@ -263,6 +264,7 @@
{"windows", no_argument, &use_windows, 1},
{"statistics", no_argument, 0, 13},
{"write", no_argument, &write_files, 1},
+ {"args", no_argument, &set_args, 1},
/* Allow machine descriptions to add more options... */
#ifdef ADDITIONAL_OPTIONS
ADDITIONAL_OPTIONS
@@ -276,7 +278,7 @@
c = getopt_long_only (argc, argv, "",
long_options, &option_index);
- if (c == EOF)
+ if (c == EOF || set_args)
break;
/* Long option that takes an argument. */
@@ -432,25 +434,46 @@
use_windows = 0;
#endif
- /* OK, that's all the options. The other arguments are filenames. */
- count = 0;
- for (; optind < argc; optind++)
- switch (++count)
- {
- case 1:
- symarg = argv[optind];
- execarg = argv[optind];
- break;
- case 2:
- /* FIXME: The documentation says this can be a "ProcID". as well. */
- corearg = argv[optind];
- break;
- case 3:
- fprintf_unfiltered (gdb_stderr,
- "Excess command line arguments ignored. (%s%s)\n",
- argv[optind], (optind == argc - 1) ? "" : " ...");
- break;
- }
+ 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 other arguments are filenames. */
+ count = 0;
+ for (; optind < argc; optind++)
+ switch (++count)
+ {
+ case 1:
+ symarg = argv[optind];
+ execarg = argv[optind];
+ break;
+ case 2:
+ /* FIXME: The documentation says this can be a
+ "ProcID". as well. */
+ corearg = argv[optind];
+ break;
+ case 3:
+ fprintf_unfiltered (gdb_stderr,
+ "Excess command line arguments ignored. (%s%s)\n",
+ argv[optind], (optind == argc - 1) ? "" : " ...");
+ break;
+ }
+ }
if (batch)
quiet = 1;
}
@@ -713,8 +736,12 @@
{
fputs_unfiltered ("\
This is the GNU debugger. Usage:\n\n\
- gdb [options] [executable-file [core-file or process-id]]\n\n\
+ gdb [options] [executable-file [core-file or process-id]]\n\
+ gdb [options] --args executable-file [inferior-arguments ...]\n\n\
Options:\n\n\
+", stream);
+ fputs_unfiltered ("\
+ --args Arguments after executable-file are passed to inferior\n\
", stream);
fputs_unfiltered ("\
--[no]async Enable (disable) asynchronous version of CLI\n\
Index: procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.32
diff -u -r1.32 procfs.c
--- procfs.c 2001/07/07 21:55:28 1.32
+++ procfs.c 2001/10/10 21:57:36
@@ -117,6 +117,7 @@
static void procfs_kill_inferior (void);
static void procfs_mourn_inferior (void);
static void procfs_create_inferior (char *, char *, char **);
+static char *procfs_construct_inferior_arguments (int, char **);
static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
struct mem_attrib *attrib,
@@ -139,6 +140,8 @@
procfs_ops.to_open = procfs_open;
procfs_ops.to_can_run = procfs_can_run;
procfs_ops.to_create_inferior = procfs_create_inferior;
+ procfs_ops.to_construct_inferior_arguments
+ = procfs_construct_inferior_arguments;
procfs_ops.to_kill = procfs_kill_inferior;
procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
procfs_ops.to_attach = procfs_attach;
@@ -5085,6 +5088,12 @@
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+}
+
+static char *
+procfs_construct_inferior_arguments (int argc, char **argv)
+{
+ return construct_inferior_arguments (argc, argv);
}
/*
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.28
diff -u -r1.28 target.c
--- target.c 2001/07/19 18:09:11 1.28
+++ target.c 2001/10/10 21:57:38
@@ -1195,6 +1195,17 @@
return;
}
+char *
+find_default_construct_inferior_arguments (int argc, char **argv)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target ("run");
+ if (t->to_construct_inferior_arguments == NULL)
+ error ("this target doesn't support command line arguments");
+ return (t->to_construct_inferior_arguments) (argc, argv);
+}
+
void
find_default_clone_and_follow_inferior (int child_pid, int *followed_child)
{
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.20
diff -u -r1.20 target.h
--- target.h 2001/08/11 00:59:29 1.20
+++ target.h 2001/10/10 21:57:39
@@ -261,6 +261,7 @@
void (*to_load) (char *, int);
int (*to_lookup_symbol) (char *, CORE_ADDR *);
void (*to_create_inferior) (char *, char *, char **);
+ char *(*to_construct_inferior_arguments) (int, char **);
void (*to_post_startup_inferior) (ptid_t);
void (*to_acknowledge_created_inferior) (int);
void (*to_clone_and_follow_inferior) (int, int *);
@@ -649,7 +650,18 @@
#define target_create_inferior(exec_file, args, env) \
(*current_target.to_create_inferior) (exec_file, args, env)
+/* Given a vector of command-line arguments, return a newly allocated
+ string which, when passed to the create_inferior function, will be
+ parsed (on Unix systems, by the shell) to yield the same vector.
+ This function should call error() if the argument vector is not
+ representable for this target or if this target does not support
+ command-line arguments.
+ ARGC is the number of elements in the vector.
+ ARGV is an array of strings, one per argument. */
+#define target_construct_inferior_arguments(argc, argv) \
+ (*current_target.to_construct_inferior_arguments) (argc, argv)
+
/* Some targets (such as ttrace-based HPUX) don't allow us to request
notification of inferior events such as fork and vork immediately
after the inferior is created. (This because of how gdb gets an
@@ -1188,6 +1200,8 @@
extern void find_default_require_detach (int, char *, int);
extern void find_default_create_inferior (char *, char *, char **);
+
+extern char *find_default_construct_inferior_arguments (int, char **);
extern void find_default_clone_and_follow_inferior (int, int *);
Index: cli/cli-decode.h
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-decode.h,v
retrieving revision 1.4
diff -u -r1.4 cli-decode.h
--- cli/cli-decode.h 2001/09/30 16:16:16 1.4
+++ cli/cli-decode.h 2001/10/10 21:57:39
@@ -128,7 +128,7 @@
/* If type is not_set_cmd, call it like this: */
void (*cfunc) (char *args, int from_tty);
- /* If type is cmd_set or show_cmd, first set the variables, and
+ /* If type is set_cmd or show_cmd, first set the variables, and
then call this. */
void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c);
}
@@ -165,6 +165,10 @@
/* if this command is deprecated, this is the replacement name */
char *replacement;
+
+ /* If this command represents a show command, then this function
+ is called before the variable's value is examined. */
+ void (*pre_show_hook) (struct cmd_list_element *c);
/* Hook for another command to be executed before this command. */
struct cmd_list_element *hook_pre;
Index: cli/cli-setshow.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-setshow.c,v
retrieving revision 1.4
diff -u -r1.4 cli-setshow.c
--- cli/cli-setshow.c 2001/05/12 04:08:24 1.4
+++ cli/cli-setshow.c 2001/10/10 21:57:40
@@ -267,6 +267,10 @@
old_chain = make_cleanup_ui_out_stream_delete (stb);
#endif /* UI_OUT */
+ /* Possibly call the pre hook. */
+ if (c->pre_show_hook)
+ (c->pre_show_hook) (c);
+
/* Print doc minus "show" at start. */
print_doc_line (gdb_stdout, c->doc + 5);
Index: doc/ChangeLog
from Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Invoking GDB): Document --args.
(Mode Options): Likewise.
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.51
diff -u -r1.51 gdb.texinfo
--- doc/gdb.texinfo 2001/09/12 19:49:52 1.51
+++ doc/gdb.texinfo 2001/10/10 21:57:58
@@ -752,6 +752,15 @@
``process'', and there is often no way to get a core dump. @value{GDBN}
will warn you if it is unable to attach or to read core dumps.
+You can optionally have @code{@value{GDBP}} pass any arguments after the
+executable file to the inferior using @code{--args}. This option stops
+option processing.
+@example
+gdb --args gcc -O2 -c foo.c
+@end example
+This will cause @code{@value{GDBP}} to debug @code{gcc}, and to set
+@code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 -c foo.c}.
+
You can run @code{@value{GDBP}} without printing the front material, which describes
@value{GDBN}'s non-warranty, by specifying @code{-silent}:
@@ -1014,6 +1023,12 @@
@item -noasync
@cindex @code{--noasync}
Disable the asynchronous event loop for the command-line interface.
+
+@item --args
+@cindex @code{--args}
+Change interpretation of command line so that arguments following the
+executable file are passed as command line arguments to the inferior.
+This option stops option processing.
@item -baud @var{bps}
@itemx -b @var{bps}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-10 15:28 PATCH: gdb --args Tom Tromey
@ 2001-10-11 1:02 ` Eli Zaretskii
2001-10-11 8:32 ` Andrew Cagney
1 sibling, 0 replies; 8+ messages in thread
From: Eli Zaretskii @ 2001-10-11 1:02 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On 10 Oct 2001, Tom Tromey wrote:
> Ok to commit?
Thanks.
The patch to gdb.texinfo is approved, with these minor comments:
> +You can optionally have @code{@value{GDBP}} pass any arguments after the
Please use @value{GDBN} here, and please don't use @code around it.
GDBP expands into "(gdb)", the GDB command-line prompt, not to "GDB".
> You can run @code{@value{GDBP}} without printing the front material, which describes
This line (which already was in the manual) has the same error. Could
you please correct it as well?
> +@item --args
> +@cindex @code{--args}
> +Change interpretation of command line so that arguments following the
> +executable file are passed as command line arguments to the inferior.
> +This option stops option processing.
Unless I misunderstand what you wanted to say, I think the last
sentence would be clearer if you say "This option stops processing of
any further options."
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-10 15:28 PATCH: gdb --args Tom Tromey
2001-10-11 1:02 ` Eli Zaretskii
@ 2001-10-11 8:32 ` Andrew Cagney
2001-10-11 9:56 ` Eli Zaretskii
2001-10-11 10:14 ` Tom Tromey
1 sibling, 2 replies; 8+ messages in thread
From: Andrew Cagney @ 2001-10-11 8:32 UTC (permalink / raw)
To: tromey; +Cc: gdb-patches
> * target.c (find_default_construct_inferior_arguments): New
> function.
> * target.h (target_ops): Added to_construct_inferior_arguments.
> (target_construct_inferior_arguments): New macro.
> (find_default_construct_inferior_arguments): Declare.
Hmm, me :-)
Is this an architecture (well OS) or target method?
At present there is the target method:
to_create_inferior(char *exec_file, char *args, char **env)
where ARGS are assumed to be in an OS dependant form but typically ready
to plonk onto the end of ``exec EXEC_FILE''. The plonk might be
performed locally (fork/exec) or remotely.
Given an argv[], I think the code should call on the architecture (OS)
and not the target to perform the transformation into ARGS.
(This will actually make the change a lot simplier. The default method
can do as for UNIX, just djgpp and possibly cygwin would need
customization.)
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-11 8:32 ` Andrew Cagney
@ 2001-10-11 9:56 ` Eli Zaretskii
2001-10-11 10:24 ` Andrew Cagney
2001-10-11 10:14 ` Tom Tromey
1 sibling, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2001-10-11 9:56 UTC (permalink / raw)
To: ac131313; +Cc: tromey, gdb-patches
> Date: Thu, 11 Oct 2001 11:32:02 -0400
> From: Andrew Cagney <ac131313@cygnus.com>
>
> Is this an architecture (well OS) or target method?
What do you mean by ``OS''? The host? Or those "#ifdef __MSDOS__"
thingies?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-11 8:32 ` Andrew Cagney
2001-10-11 9:56 ` Eli Zaretskii
@ 2001-10-11 10:14 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2001-10-11 10:14 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
Tom> * target.c (find_default_construct_inferior_arguments): New
Tom> function.
Andrew> Is this an architecture (well OS) or target method?
Andrew> At present there is the target method:
Andrew> to_create_inferior(char *exec_file, char *args, char **env)
Andrew> where ARGS are assumed to be in an OS dependant form but
Andrew> typically ready to plonk onto the end of ``exec EXEC_FILE''.
Andrew> The plonk might be performed locally (fork/exec) or remotely.
As I understood it, to_create_inferior assumed that ARGS was properly
quoted for the target. To me this implies that the transformation
from argv[] to string must be done in a target-dependent way -- that
is, in a way that matches what the corresponding to_create_inferior
expects.
Andrew> Given an argv[], I think the code should call on the
Andrew> architecture (OS) and not the target to perform the
Andrew> transformation into ARGS.
I think this will do the wrong thing in some situations.
Here's a hypothetical situation. Suppose you can somehow debug a Unix
program from a Windows machine. In this Windows gdb you can use "run"
and some server on the Unix box will use the code in fork-inferior.c
to run a new inferior.
In this case, quoting based on the host would be incorrectly quoted --
it would be quoted by Windows conventions but the target would be
expecting Unix conventions.
I dug around in the code a bit and came up with a real example.
Suppose I am debugging a remote VxWorks process using a gdb running on
my Linux box.
remote-vx.c:parse_args() does some very simple command-line
processing. It just splits the command-line at whitespace.
If you run an argv[] through the Unix stringizer, you'll get the wrong
result for this target -- for instance, if an argument has a space the
"right" result would be an error message: "you can't do that". But
the result you'd actually get would have added trailing backslashes to
various arguments.
Another similar example is that the simulators use buildargv (from
libiberty) to turn a string into an argument vector. The simulators
can be used on any host, but the argv[]->string step must create a
string which buildargv will parse back into the same argv[]. This
also implies that the stringizing must be done on a per-target basis.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-11 9:56 ` Eli Zaretskii
@ 2001-10-11 10:24 ` Andrew Cagney
2001-10-11 10:29 ` Tom Tromey
0 siblings, 1 reply; 8+ messages in thread
From: Andrew Cagney @ 2001-10-11 10:24 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: tromey, gdb-patches
>> Date: Thu, 11 Oct 2001 11:32:02 -0400
>> From: Andrew Cagney <ac131313@cygnus.com>
>>
>> Is this an architecture (well OS) or target method?
>
>
> What do you mean by ``OS''? The host? Or those "#ifdef __MSDOS__"
> thingies?
The target's operating system. I think the target's operating system is
something independant of the actual interface (ptrace, procfs, remote,
...) GDB uses to control the target program.
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-11 10:24 ` Andrew Cagney
@ 2001-10-11 10:29 ` Tom Tromey
2001-10-11 10:49 ` Andrew Cagney
0 siblings, 1 reply; 8+ messages in thread
From: Tom Tromey @ 2001-10-11 10:29 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Eli Zaretskii, gdb-patches
>>>>> "Andrew" == Andrew Cagney <ac131313@cygnus.com> writes:
Andrew> The target's operating system. I think the target's operating
Andrew> system is something independant of the actual interface
Andrew> (ptrace, procfs, remote, ...) GDB uses to control the target
Andrew> program.
Is there a target OS vector or something like that?
I don't understand how the code would look if I made this change.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: gdb --args
2001-10-11 10:29 ` Tom Tromey
@ 2001-10-11 10:49 ` Andrew Cagney
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Cagney @ 2001-10-11 10:49 UTC (permalink / raw)
To: tromey; +Cc: Eli Zaretskii, gdb-patches
>>>> "Andrew" == Andrew Cagney <ac131313@cygnus.com> writes:
>
>
> Andrew> The target's operating system. I think the target's operating
> Andrew> system is something independant of the actual interface
> Andrew> (ptrace, procfs, remote, ...) GDB uses to control the target
> Andrew> program.
>
> Is there a target OS vector or something like that?
> I don't understand how the code would look if I made this change.
Yes. Only thanks to a legacy of unfortunate name choices (target.[hc])
it is called gdbarch.
The code would look almost identical only instead of calling a
target.[hc] method it would call an architecture method.
I'll resist the temptation of suggesting that ``register_read'' would
make a good example - the x86 isn't multi-arch and wouldn't be able to
use it :-/ Can I instead suggest something like target_read_pc.
--
I think most of the other changes are CLI and (a little) top.c related
(even though the sit in infcmd.c). I'll defer to other maintainers for
comments on that.
Andrew
PS: The below is for reference, and was part of a reply to an earlier
e-mail.
> As I understood it, to_create_inferior assumed that ARGS was properly
> quoted for the target. To me this implies that the transformation
> from argv[] to string must be done in a target-dependent way -- that
> is, in a way that matches what the corresponding to_create_inferior
> expects.
GDB suffers from some really badly chosen terminology. ``target'' is
badly overloaded.
I wasn't exactly clear in what I ment by ``architecture (well OS)'', sorry.
The system being debugged will have:
- an interface to control the target being debugged
In GDB that is the target.[hc] jumbo object.
GDB uses this interface to perform operations such as step, continue,
kill and start the system being debugged. It might use ptrace, procfs,
remote or nothing (core).
- an interface describing the systems ISA, ABI and OS
In GDB that is the gdbarch.[hc] jumbo object.
GDB calls on the gdbarch object when doing things that are dependant on
the target architecture rather than the details of the target interface.
For instance, shared library support, an OS feature, is managed by
gdbarch and not the target vector.
I think what you're doing is independant of the control interface
(target.[hc]) but is target operating system dependant. Hence
suggesting that it live in gdbarch.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2001-10-11 10:49 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-10 15:28 PATCH: gdb --args Tom Tromey
2001-10-11 1:02 ` Eli Zaretskii
2001-10-11 8:32 ` Andrew Cagney
2001-10-11 9:56 ` Eli Zaretskii
2001-10-11 10:24 ` Andrew Cagney
2001-10-11 10:29 ` Tom Tromey
2001-10-11 10:49 ` Andrew Cagney
2001-10-11 10:14 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox