* 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.

	* 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.
This commit is contained in:
Daniel Jacobowitz 2008-03-10 23:14:06 +00:00
parent 42e344a77c
commit ccd213ac7e
8 changed files with 201 additions and 10 deletions

View 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".

View 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) \

View file

@ -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

View 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

View 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.

View 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);
}

View 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

View 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