Fix for PR gdb/209, PR gdb/156:

* gdbarch.c, gdbarch.h: Rebuilt.
	* gdbarch.sh: Added `construct_inferior_arguments'.
	* 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.
	(set_inferior_args_vector): Likewise.
	* fork-child.c (construct_inferior_arguments): New function.
This commit is contained in:
Tom Tromey 2001-11-22 00:23:13 +00:00
parent aa26fa3a7e
commit 552c04a742
11 changed files with 268 additions and 28 deletions

View File

@ -1,3 +1,28 @@
2001-11-21 Tom Tromey <tromey@redhat.com>
Fix for PR gdb/209, PR gdb/156:
* gdbarch.c, gdbarch.h: Rebuilt.
* gdbarch.sh: Added `construct_inferior_arguments'.
* 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.
(set_inferior_args_vector): Likewise.
* fork-child.c (construct_inferior_arguments): New function.
2001-11-21 Kevin Buettner <kevinb@redhat.com>
* lin-lwp.c (lin_lwp_attach_lwp): Make sure SIGCHLD is in set of

View File

@ -128,7 +128,7 @@ struct cmd_list_element
/* 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);
}
@ -166,6 +166,10 @@ struct cmd_list_element
/* 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;

View File

@ -267,6 +267,10 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
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);

View File

@ -134,7 +134,7 @@ struct cmd_list_element
/* 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);
}
@ -172,6 +172,10 @@ struct cmd_list_element
/* 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;

View File

@ -568,3 +568,74 @@ startup_inferior (int ntraps)
#endif /* STARTUP_INFERIOR */
stop_soon_quietly = 0;
}
/* Compute command-line string given argument vector. This does the
same shell processing as fork_inferior. */
/* ARGSUSED */
char *
construct_inferior_arguments (struct gdbarch *gdbarch, 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;
}

View File

@ -255,6 +255,7 @@ struct gdbarch
gdbarch_skip_trampoline_code_ftype *skip_trampoline_code;
gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline;
gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p;
gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments;
};
@ -394,6 +395,7 @@ struct gdbarch startup_gdbarch =
0,
0,
generic_in_function_epilogue_p,
construct_inferior_arguments,
/* startup_gdbarch() */
};
@ -504,6 +506,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline;
current_gdbarch->in_function_epilogue_p = generic_in_function_epilogue_p;
current_gdbarch->construct_inferior_arguments = construct_inferior_arguments;
/* gdbarch_alloc() */
return current_gdbarch;
@ -755,6 +758,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of skip_trampoline_code, invalid_p == 0 */
/* Skip verify of in_solib_call_trampoline, invalid_p == 0 */
/* Skip verify of in_function_epilogue_p, invalid_p == 0 */
/* Skip verify of construct_inferior_arguments, invalid_p == 0 */
buf = ui_file_xstrdup (log, &dummy);
make_cleanup (xfree, buf);
if (strlen (buf) > 0)
@ -962,6 +966,10 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
(long) current_gdbarch->coerce_float_to_double
/*COERCE_FLOAT_TO_DOUBLE ()*/);
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
"gdbarch_dump: construct_inferior_arguments = 0x%08lx\n",
(long) current_gdbarch->construct_inferior_arguments);
#ifdef CONVERT_FROM_FUNC_PTR_ADDR
fprintf_unfiltered (file,
"gdbarch_dump: %s # %s\n",
@ -4270,6 +4278,24 @@ set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch,
gdbarch->in_function_epilogue_p = in_function_epilogue_p;
}
char *
gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
{
if (gdbarch->construct_inferior_arguments == 0)
internal_error (__FILE__, __LINE__,
"gdbarch: gdbarch_construct_inferior_arguments invalid");
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_construct_inferior_arguments called\n");
return gdbarch->construct_inferior_arguments (gdbarch, argc, argv);
}
void
set_gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch,
gdbarch_construct_inferior_arguments_ftype construct_inferior_arguments)
{
gdbarch->construct_inferior_arguments = construct_inferior_arguments;
}
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */

View File

@ -2113,6 +2113,19 @@ typedef int (gdbarch_in_function_epilogue_p_ftype) (struct gdbarch *gdbarch, COR
extern int gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr);
extern void set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p);
/* 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. */
typedef char * (gdbarch_construct_inferior_arguments_ftype) (struct gdbarch *gdbarch, int argc, char **argv);
extern char * gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv);
extern void set_gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments);
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);

View File

@ -560,6 +560,15 @@ f:2:IN_SOLIB_CALL_TRAMPOLINE:int:in_solib_call_trampoline:CORE_ADDR pc, char *na
# which don't suffer from that problem could just let this functionality
# untouched.
m:::int:in_function_epilogue_p:CORE_ADDR addr:addr::0:generic_in_function_epilogue_p::0
# 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.
m::CONSTRUCT_INFERIOR_ARGUMENTS:char *:construct_inferior_arguments:int argc, char **argv:argc, argv:::construct_inferior_arguments::0
EOF
}

View File

@ -123,6 +123,12 @@ static void breakpoint_auto_delete_contents (PTR);
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 @@ struct environ *inferior_environ;
char *
get_inferior_args (void)
{
if (inferior_argc != 0)
{
char *n, *old;
n = gdbarch_construct_inferior_arguments (current_gdbarch,
inferior_argc, inferior_argv);
old = set_inferior_args (n);
xfree (old);
}
if (inferior_args == NULL)
inferior_args = xstrdup ("");
return inferior_args;
}
@ -208,10 +227,37 @@ set_inferior_args (char *newargs)
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 +377,9 @@ Start it from the beginning? "))
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 +387,17 @@ Start it from the beginning? "))
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));
}
@ -1785,8 +1837,10 @@ _initialize_infcmd (void)
"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,
@ -1952,7 +2006,6 @@ Register name as argument means describe only that register.");
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);
}

View File

@ -270,6 +270,8 @@ extern void clone_and_follow_inferior (int, int *);
extern void startup_inferior (int);
extern char *construct_inferior_arguments (struct gdbarch *, int, char **);
/* From inflow.c */
extern void new_tty_prefork (char *);
@ -307,6 +309,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). */
extern enum target_signal stop_signal;

View File

@ -124,6 +124,7 @@ captured_main (void *data)
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 @@ captured_main (void *data)
{"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 @@ captured_main (void *data)
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 @@ extern int gdbtk_test (char *);
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 @@ print_gdb_help (struct ui_file *stream)
{
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\