This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: gdb --args


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}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]