* Makefile.in (fork-child.o): Update.
authorDaniel Jacobowitz <drow@false.org>
Mon, 10 Mar 2008 23:14:06 +0000 (23:14 +0000)
committerDaniel Jacobowitz <drow@false.org>
Mon, 10 Mar 2008 23:14:06 +0000 (23:14 +0000)
* NEWS: Document "set exec-wrapper" and the gdbserver --wrapper
argument.  Gather all gdbserver features together.
* fork-child.c (exec_wrapper): New variable.
(fork_inferior): Use it.
(startup_inferior): Skip an extra trap if using "set exec-wrapper".
(unset_exec_wrapper_command, _initialize_fork_child): New.

* gdb.texinfo (Starting): Document "set exec-wrapper".
(Server): Document gdbserver --wrapper.

* server.c (wrapper_argv): New.
(start_inferior): Handle wrapper_argv.  If set, expect an extra
trap.
(gdbserver_usage): Document --wrapper.
(main): Parse --wrapper.

gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/fork-child.c
gdb/gdbserver/ChangeLog
gdb/gdbserver/server.c

index b53c05c546919a6d764f1cd84ad2df5b123bc596..a9a1696e120ea68f86192c0f9020cfecfd1cc649 100644 (file)
@@ -1,4 +1,14 @@
-2008-03-06  Hidetaka Takano <hidetaka.takano@glb.toshiba.co.jp>
+2008-03-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * Makefile.in (fork-child.o): Update.
+       * NEWS: Document "set exec-wrapper" and the gdbserver --wrapper
+       argument.  Gather all gdbserver features together.
+       * fork-child.c (exec_wrapper): New variable.
+       (fork_inferior): Use it.
+       (startup_inferior): Skip an extra trap if using "set exec-wrapper".
+       (unset_exec_wrapper_command, _initialize_fork_child): New.
+
+2008-03-10  Hidetaka Takano  <hidetaka.takano@glb.toshiba.co.jp>
 
        * source.c (directory_command): Modify the determination of
        condition of terminal "from_tty".
index bcf7581e1ee306ad878fa3abf37d54b6c9e907c3..5cf5131259b94baa22a21d07a63c0e32a1159da8 100644 (file)
@@ -2110,7 +2110,7 @@ f-lang.o: f-lang.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
        $(valprint_h) $(value_h)
 fork-child.o: fork-child.c $(defs_h) $(gdb_string_h) $(frame_h) \
        $(inferior_h) $(target_h) $(gdb_wait_h) $(gdb_vfork_h) $(gdbcore_h) \
-       $(terminal_h) $(gdbthread_h) $(command_h) $(solib_h)
+       $(terminal_h) $(gdbthread_h) $(command_h) $(gdbcmd_h) $(solib_h)
 frame-base.o: frame-base.c $(defs_h) $(frame_base_h) $(frame_h) \
        $(gdb_obstack_h)
 frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \
index b689f8cdcfd7a6f3c36fb8a4ca4eaf44685a13c9..4aba328fcdc39565d1af4d3e5cdd9d60bab0187a 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,14 +3,24 @@
 
 *** Changes since GDB 6.8
 
+* Watchpoints can now be set on unreadable memory locations, e.g. addresses
+which will be allocated using malloc later in program execution.
+
+* New features in the GDB remote stub, gdbserver
+
+  - The "--wrapper" command-line argument tells gdbserver to use a
+  wrapper program to launch programs for debugging.
+
 * New commands
 
 set debug timetstamp
 show debug timestamp
   Display timestamps with GDB debugging output.
 
-* Watchpoints can now be set on unreadable memory locations, e.g. addresses
-which will be allocated using malloc later in program execution.
+set exec-wrapper
+show exec-wrapper
+unset exec-wrapper
+  Use a wrapper program to launch programs for debugging.
 
 *** Changes in GDB 6.8
 
index 6e688990f5ba19bc5a3c27232cfbba7c5a38c01f..096e2848cafbd104e1d3d59c2dbe20038bff9b91 100644 (file)
@@ -1,3 +1,8 @@
+2008-03-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb.texinfo (Starting): Document "set exec-wrapper".
+       (Server): Document gdbserver --wrapper.
+
 2008-03-03  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * gdb.texinfo (Set Watchpoints): Mention watchpoints on
index 1a0e9d263e0bab75eb1d38dedaf49c941cbf7624..dbc9efc3f0a517177ad1468ae21a142e5c19f7dc 100644 (file)
@@ -1921,6 +1921,36 @@ these cases, using the @code{start} command would stop the execution of
 your program too late, as the program would have already completed the
 elaboration phase.  Under these circumstances, insert breakpoints in your
 elaboration code before running your program.
+
+@kindex set exec-wrapper
+@item set exec-wrapper @var{wrapper}
+@itemx show exec-wrapper
+@itemx unset exec-wrapper
+When @samp{exec-wrapper} is set, the specified wrapper is used to
+launch programs for debugging.  @value{GDBN} starts your program
+with a shell command of the form @kbd{exec @var{wrapper}
+@var{program}}.  Quoting is added to @var{program} and its
+arguments, but not to @var{wrapper}, so you should add quotes if
+appropriate for your shell.  The wrapper runs until it executes
+your program, and then @value{GDBN} takes control.
+
+You can use any program that eventually calls @code{execve} with
+its arguments as a wrapper.  Several standard Unix utilities do
+this, e.g.@: @code{env} and @code{nohup}.  Any Unix shell script ending
+with @code{exec "$@@"} will also work.
+
+For example, you can use @code{env} to pass an environment variable to
+the debugged program, without setting the variable in your shell's
+environment:
+
+@smallexample
+(@value{GDBP}) set exec-wrapper env 'LD_PRELOAD=libtest.so'
+(@value{GDBP}) run
+@end smallexample
+
+This command is available when debugging locally on most targets, excluding
+@sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
+
 @end table
 
 @node Arguments
@@ -13083,6 +13113,29 @@ You can include @option{--debug} on the @code{gdbserver} command line.
 process.  This option is intended for @code{gdbserver} development and
 for bug reports to the developers.
 
+The @option{--wrapper} option specifies a wrapper to launch programs
+for debugging.  The option should be followed by the name of the
+wrapper, then any command-line arguments to pass to the wrapper, then
+@kbd{--} indicating the end of the wrapper arguments.
+
+@code{gdbserver} runs the specified wrapper program with a combined
+command line including the wrapper arguments, then the name of the
+program to debug, then any arguments to the program.  The wrapper
+runs until it executes your program, and then @value{GDBN} gains control.
+
+You can use any program that eventually calls @code{execve} with
+its arguments as a wrapper.  Several standard Unix utilities do
+this, e.g.@: @code{env} and @code{nohup}.  Any Unix shell script ending
+with @code{exec "$@@"} will also work.
+
+For example, you can use @code{env} to pass an environment variable to
+the debugged program, without setting the variable in @code{gdbserver}'s
+environment:
+
+@smallexample
+$ gdbserver --wrapper env LD_PRELOAD=libtest.so -- :2222 ./testprog
+@end smallexample
+
 @subsection Connecting to @code{gdbserver}
 
 Run @value{GDBN} on the host system.
index 15b8245feed89b32a6b97e47a5ef33fe942e3484..cbde5dbfac420c5c96612ac437f963e62b1f47ea 100644 (file)
@@ -31,6 +31,7 @@
 #include "terminal.h"
 #include "gdbthread.h"
 #include "command.h" /* for dont_repeat () */
+#include "gdbcmd.h"
 #include "solib.h"
 
 #include <signal.h>
@@ -40,6 +41,8 @@
 
 extern char **environ;
 
+static char *exec_wrapper;
+
 /* Break up SCRATCH into an argument vector suitable for passing to
    execvp and store it in ARGV.  E.g., on "run a b c d" this routine
    would get as input the string "a b c d", and as output it would
@@ -160,6 +163,9 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
      fact that it may expand when quoted; it is a worst-case number
      based on every character being '.  */
   len = 5 + 4 * strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop */ 12;
+  if (exec_wrapper)
+    len += strlen (exec_wrapper) + 1;
+
   shell_command = (char *) alloca (len);
   shell_command[0] = '\0';
 
@@ -178,14 +184,22 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
     {
       /* We're going to call a shell.  */
 
-      /* Now add exec_file, quoting as necessary.  */
-
       char *p;
       int need_to_quote;
       const int escape_bang = escape_bang_in_quoted_argument (shell_file);
 
       strcat (shell_command, "exec ");
 
+      /* Add any exec wrapper.  That may be a program name with arguments, so
+        the user must handle quoting.  */
+      if (exec_wrapper)
+       {
+         strcat (shell_command, exec_wrapper);
+         strcat (shell_command, " ");
+       }
+
+      /* Now add exec_file, quoting as necessary.  */
+
       /* Quoting in this style is said to work with all shells.  But
          csh on IRIX 4.0.1 can't deal with it.  So we only quote it if
          we need to.  */
@@ -399,6 +413,9 @@ startup_inferior (int ntraps)
      have stopped one instruction after execing the shell.  Here we
      must get it up to actual execution of the real program.  */
 
+  if (exec_wrapper)
+    pending_execs++;
+
   clear_proceed_status ();
 
   init_wait_for_inferior ();
@@ -446,3 +463,28 @@ startup_inferior (int ntraps)
     }
   stop_soon = NO_STOP_QUIETLY;
 }
+
+/* Implement the "unset exec-wrapper" command.  */
+
+static void
+unset_exec_wrapper_command (char *args, int from_tty)
+{
+  xfree (exec_wrapper);
+  exec_wrapper = NULL;
+}
+
+void
+_initialize_fork_child (void)
+{
+  add_setshow_filename_cmd ("exec-wrapper", class_run, &exec_wrapper, _("\
+Set a wrapper for running programs.\n\
+The wrapper prepares the system and environment for the new program."),
+                           _("\
+Show the wrapper for running programs."), NULL,
+                           NULL, NULL,
+                           &setlist, &showlist);
+
+  add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
+           _("Disable use of an execution wrapper."),
+           &unsetlist);
+}
index a59668cc644400fc451bd0103c95b510034e2668..e25f236089d0bc34d9b87bdefe2c349d69d4b525 100644 (file)
@@ -1,3 +1,11 @@
+2008-03-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * server.c (wrapper_argv): New.
+       (start_inferior): Handle wrapper_argv.  If set, expect an extra
+       trap.
+       (gdbserver_usage): Document --wrapper.
+       (main): Parse --wrapper.
+
 2008-02-28  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * configure.srv [powerpc64-*-linux*]: Add all files mentioned for
index 7806bd6bf8b06eeb182511a8680709384387fc72..634bf806e4e057607426d05ccbd68d1a0b7704e9 100644 (file)
@@ -41,7 +41,7 @@ static int attached;
 static int response_needed;
 static int exit_requested;
 
-static char **program_argv;
+static char **program_argv, **wrapper_argv;
 
 /* Enable miscellaneous debugging output.  The name is historical - it
    was originally used to debug LinuxThreads support.  */
@@ -83,16 +83,34 @@ target_running (void)
 }
 
 static int
-start_inferior (char *argv[], char *statusptr)
+start_inferior (char **argv, char *statusptr)
 {
+  char **new_argv = argv;
   attached = 0;
 
+  if (wrapper_argv != NULL)
+    {
+      int i, count = 1;
+
+      for (i = 0; wrapper_argv[i] != NULL; i++)
+       count++;
+      for (i = 0; argv[i] != NULL; i++)
+       count++;
+      new_argv = alloca (sizeof (char *) * count);
+      count = 0;
+      for (i = 0; wrapper_argv[i] != NULL; i++)
+       new_argv[count++] = wrapper_argv[i];
+      for (i = 0; argv[i] != NULL; i++)
+       new_argv[count++] = argv[i];
+      new_argv[count] = NULL;
+    }
+
 #ifdef SIGTTOU
   signal (SIGTTOU, SIG_DFL);
   signal (SIGTTIN, SIG_DFL);
 #endif
 
-  signal_pid = create_inferior (argv[0], argv);
+  signal_pid = create_inferior (new_argv[0], new_argv);
 
   /* FIXME: we don't actually know at this point that the create
      actually succeeded.  We won't know that until we wait.  */
@@ -109,6 +127,33 @@ start_inferior (char *argv[], char *statusptr)
   atexit (restore_old_foreground_pgrp);
 #endif
 
+  if (wrapper_argv != NULL)
+    {
+      struct thread_resume resume_info;
+      int sig;
+
+      resume_info.thread = -1;
+      resume_info.step = 0;
+      resume_info.sig = 0;
+      resume_info.leave_stopped = 0;
+
+      sig = mywait (statusptr, 0);
+      if (*statusptr != 'T')
+       return sig;
+
+      do
+       {
+         (*the_target->resume) (&resume_info);
+
+         sig = mywait (statusptr, 0);
+         if (*statusptr != 'T')
+           return sig;
+       }
+      while (sig != TARGET_SIGNAL_TRAP);
+
+      return sig;
+    }
+
   /* Wait till we are at 1st instruction in program, return signal
      number (assuming success).  */
   return mywait (statusptr, 0);
@@ -1002,7 +1047,8 @@ gdbserver_usage (void)
          "HOST:PORT to listen for a TCP connection.\n"
          "\n"
          "Options:\n"
-         "  --debug\t\tEnable debugging output.\n");
+         "  --debug\t\tEnable debugging output.\n"
+         "  --wrapper WRAPPER --\tRun WRAPPER to start new programs.\n");
 }
 
 #undef require_running
@@ -1046,6 +1092,23 @@ main (int argc, char *argv[])
        attach = 1;
       else if (strcmp (*next_arg, "--multi") == 0)
        multi_mode = 1;
+      else if (strcmp (*next_arg, "--wrapper") == 0)
+       {
+         next_arg++;
+
+         wrapper_argv = next_arg;
+         while (*next_arg != NULL && strcmp (*next_arg, "--") != 0)
+           next_arg++;
+
+         if (next_arg == wrapper_argv || *next_arg == NULL)
+           {
+             gdbserver_usage ();
+             exit (1);
+           }
+
+         /* Consume the "--".  */
+         *next_arg = NULL;
+       }
       else if (strcmp (*next_arg, "--debug") == 0)
        debug_threads = 1;
       else