Make STARTUP_WITH_SHELL a runtime toggle -- add new "set/show startup-with-shell" option.

Occasionaly we hear about people having problems with GDB not being
able to start programs (with "run"/"start").  GDB spawns a shell to
start the program, and most often, it'll be the case that the problem
is actually with the user's shell setup.

GDB has code to disable the use of the shell to start programs.
That's the STARTUP_WITH_SHELL macro that native targets could set to 0
in their nm.h file (though no target actually uses it nowadays).

This patch makes that setting a run-time knob instead.  This will be
useful to quickly diagnose such shell issues, and might also come in
handy at other times (such as when debugging the shell itself, if you
don't have a different shell handy).

gdb/
2013-10-24  Pedro Alves  <palves@redhat.com>

	* NEWS (New options): Mention set/show startup-with-shell.
	* config/alpha/nm-osf3.h (START_INFERIOR_TRAPS_EXPECTED): Set to 2
	instead of 3.
	* fork-child.c (fork_inferior, startup_inferior): Handle 'set
	startup-with-shell'.
	(show_startup_with_shell): New function.
	(_initialize_fork_child): Register the set/show startup-with-shell
	commands.
	* inf-ptrace.c (inf_ptrace_create_inferior): Remove comment.
	* inf-ttrace.c (inf_ttrace_him): Remove comment.
	* procfs.c (procfs_init_inferior): Remove comment.
	* infcmd.c (startup_with_shell): New global.
	* inferior.h (startup_with_shell): Declare global.
	(STARTUP_WITH_SHELL): Delete.
	(START_INFERIOR_TRAPS_EXPECTED): Set to 1 by default instead of 2.

gdb/doc/
2013-10-24  Pedro Alves  <palves@redhat.com>

	* gdb.texinfo (Starting): Document set/show startup-with-shell.
This commit is contained in:
Pedro Alves
2013-10-24 16:10:05 +01:00
committed by Tom Tromey
parent c9737c08e7
commit 98882a2651
11 changed files with 118 additions and 37 deletions

View File

@@ -1,3 +1,21 @@
2013-10-24 Pedro Alves <palves@redhat.com>
* NEWS (New options): Mention set/show startup-with-shell.
* config/alpha/nm-osf3.h (START_INFERIOR_TRAPS_EXPECTED): Set to 2
instead of 3.
* fork-child.c (fork_inferior, startup_inferior): Handle 'set
startup-with-shell'.
(show_startup_with_shell): New function.
(_initialize_fork_child): Register the set/show startup-with-shell
commands.
* inf-ptrace.c (inf_ptrace_create_inferior): Remove comment.
* inf-ttrace.c (inf_ttrace_him): Remove comment.
* procfs.c (procfs_init_inferior): Remove comment.
* infcmd.c (startup_with_shell): New global.
* inferior.h (startup_with_shell): Declare global.
(STARTUP_WITH_SHELL): Delete.
(START_INFERIOR_TRAPS_EXPECTED): Set to 1 by default instead of 2.
2013-10-23 Pedro Alves <palves@redhat.com> 2013-10-23 Pedro Alves <palves@redhat.com>
* common/gdb_signals.h (gdb_signal_to_symbol_string): Declare. * common/gdb_signals.h (gdb_signal_to_symbol_string): Declare.

View File

@@ -98,6 +98,11 @@ set range-stepping
show range-stepping show range-stepping
Control whether target-assisted range stepping is enabled. Control whether target-assisted range stepping is enabled.
set startup-with-shell
show startup-with-shell
Specifies whether Unix child processes are started via a shell or
directly.
* You can now use a literal value 'unlimited' for options that * You can now use a literal value 'unlimited' for options that
interpret 0 or -1 as meaning "unlimited". E.g., "set interpret 0 or -1 as meaning "unlimited". E.g., "set
trace-buffer-size unlimited" is now an alias for "set trace-buffer-size unlimited" is now an alias for "set

View File

@@ -16,10 +16,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Number of traps that happen between exec'ing the shell /* Number of traps that happen between exec'ing the shell to run an
to run an inferior, and when we finally get to inferior, and when we finally get to the inferior code, not
the inferior code. This is 2 on most implementations. */ counting the exec for the shell. This is 1 on most
#define START_INFERIOR_TRAPS_EXPECTED 3 implementations. */
#define START_INFERIOR_TRAPS_EXPECTED 2
/* Don't trace faults under OSF/1, rely on the posting of the appropriate /* Don't trace faults under OSF/1, rely on the posting of the appropriate
signal if fault tracing is disabled. signal if fault tracing is disabled.

View File

@@ -1,3 +1,7 @@
2013-10-24 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Starting): Document set/show startup-with-shell.
2013-10-11 Joel Brobecker <brobecker@adacore.com> 2013-10-11 Joel Brobecker <brobecker@adacore.com>
* gdb.texinfo (Shared Library GDB/MI Catchpoint Commands): * gdb.texinfo (Shared Library GDB/MI Catchpoint Commands):

View File

@@ -2011,8 +2011,10 @@ is used to pass the arguments, so that you may use normal conventions
(such as wildcard expansion or variable substitution) in describing (such as wildcard expansion or variable substitution) in describing
the arguments. the arguments.
In Unix systems, you can control which shell is used with the In Unix systems, you can control which shell is used with the
@code{SHELL} environment variable. @code{SHELL} environment variable. If you do not define @code{SHELL},
@xref{Arguments, ,Your Program's Arguments}. @value{GDBN} uses the default shell (@file{/bin/sh}). You can disable
use of any shell with the @code{set startup-with-shell} command (see
below for details).
@item The @emph{environment.} @item The @emph{environment.}
Your program normally inherits its environment from @value{GDBN}, but you can Your program normally inherits its environment from @value{GDBN}, but you can
@@ -2115,6 +2117,32 @@ environment:
This command is available when debugging locally on most targets, excluding This command is available when debugging locally on most targets, excluding
@sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino. @sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
@kindex set startup-with-shell
@item set startup-with-shell
@itemx set startup-with-shell on
@itemx set startup-with-shell off
@itemx show set startup-with-shell
On Unix systems, by default, if a shell is available on your target,
@value{GDBN}) uses it to start your program. Arguments of the
@code{run} command are passed to the shell, which does variable
substitution, expands wildcard characters and performs redirection of
I/O. In some circumstances, it may be useful to disable such use of a
shell, for example, when debugging the shell itself or diagnosing
startup failures such as:
@smallexample
(@value{GDBP}) run
Starting program: ./a.out
During startup program terminated with signal SIGSEGV, Segmentation fault.
@end smallexample
@noindent
which indicates the shell or the wrapper specified with
@samp{exec-wrapper} crashed, not your program. Most often, this is
caused by something odd in your shell's initialization file---such as
@file{.cshrc} for C-shell, $@file{.zshenv} for the Z shell, or the
file specified in the @samp{BASH_ENV} environment variable for BASH.
@kindex set disable-randomization @kindex set disable-randomization
@item set disable-randomization @item set disable-randomization
@itemx set disable-randomization on @itemx set disable-randomization on

View File

@@ -150,11 +150,11 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
if (exec_file == 0) if (exec_file == 0)
exec_file = get_exec_file (1); exec_file = get_exec_file (1);
/* STARTUP_WITH_SHELL is defined in inferior.h. If 0,e we'll just /* 'startup_with_shell' is declared in inferior.h and bound to the
do a fork/exec, no shell, so don't bother figuring out what "set startup-with-shell" option. If 0, we'll just do a
shell. */ fork/exec, no shell, so don't bother figuring out what shell. */
shell_file = shell_file_arg; shell_file = shell_file_arg;
if (STARTUP_WITH_SHELL) if (startup_with_shell)
{ {
/* Figure out what shell to start up the user program under. */ /* Figure out what shell to start up the user program under. */
if (shell_file == NULL) if (shell_file == NULL)
@@ -419,6 +419,12 @@ startup_inferior (int ntraps)
int terminal_initted = 0; int terminal_initted = 0;
ptid_t resume_ptid; ptid_t resume_ptid;
if (startup_with_shell)
{
/* One trap extra for exec'ing the shell. */
pending_execs++;
}
if (target_supports_multi_process ()) if (target_supports_multi_process ())
resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
else else
@@ -533,6 +539,15 @@ unset_exec_wrapper_command (char *args, int from_tty)
exec_wrapper = NULL; exec_wrapper = NULL;
} }
static void
show_startup_with_shell (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file,
_("Use of shell to start subprocesses is %s.\n"),
value);
}
/* Provide a prototype to silence -Wmissing-prototypes. */ /* Provide a prototype to silence -Wmissing-prototypes. */
extern initialize_file_ftype _initialize_fork_child; extern initialize_file_ftype _initialize_fork_child;
@@ -550,4 +565,12 @@ Show the wrapper for running programs."), NULL,
add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command, add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
_("Disable use of an execution wrapper."), _("Disable use of an execution wrapper."),
&unsetlist); &unsetlist);
add_setshow_boolean_cmd ("startup-with-shell", class_support,
&startup_with_shell, _("\
Set use of shell to start subprocesses. The default is on."), _("\
Show use of shell to start subprocesses."), NULL,
NULL,
show_startup_with_shell,
&setlist, &showlist);
} }

View File

@@ -137,9 +137,6 @@ inf_ptrace_create_inferior (struct target_ops *ops,
discard_cleanups (back_to); discard_cleanups (back_to);
/* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
be 1 or 2 depending on whether we're starting without or with a
shell. */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED); startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
/* On some targets, there must be some explicit actions taken after /* On some targets, there must be some explicit actions taken after

View File

@@ -642,9 +642,6 @@ inf_ttrace_him (struct target_ops *ops, int pid)
push_target (ops); push_target (ops);
/* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
be 1 or 2 depending on whether we're starting without or with a
shell. */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED); startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
/* On some targets, there must be some explicit actions taken after /* On some targets, there must be some explicit actions taken after

View File

@@ -147,6 +147,10 @@ enum stop_stack_kind stop_stack_dummy;
int stopped_by_random_signal; int stopped_by_random_signal;
/* See inferior.h. */
int startup_with_shell = 1;
/* Accessor routines. */ /* Accessor routines. */
@@ -255,7 +259,7 @@ construct_inferior_arguments (int argc, char **argv)
{ {
char *result; char *result;
if (STARTUP_WITH_SHELL) if (startup_with_shell)
{ {
#ifdef __MINGW32__ #ifdef __MINGW32__
/* This holds all the characters considered special to the /* This holds all the characters considered special to the

View File

@@ -257,6 +257,25 @@ extern void notice_new_inferior (ptid_t, int, int);
extern struct value *get_return_value (struct value *function, extern struct value *get_return_value (struct value *function,
struct type *value_type); struct type *value_type);
/* Whether to start up the debuggee under a shell.
If startup-with-shell is set, GDB's "run" will attempt to start up
the debuggee under a shell.
This is in order for argument-expansion to occur. E.g.,
(gdb) run *
The "*" gets expanded by the shell into a list of files.
While this is a nice feature, it may be handy to bypass the shell
in some cases. To disable this feature, do "set startup-with-shell
false".
The catch-exec traps expected during start-up will be one more if
the target is started up with a shell. */
extern int startup_with_shell;
/* Address at which inferior stopped. */ /* Address at which inferior stopped. */
extern CORE_ADDR stop_pc; extern CORE_ADDR stop_pc;
@@ -346,25 +365,12 @@ struct displaced_step_closure *get_displaced_step_closure_by_addr (CORE_ADDR add
#define ON_STACK 1 #define ON_STACK 1
#define AT_ENTRY_POINT 4 #define AT_ENTRY_POINT 4
/* If STARTUP_WITH_SHELL is set, GDB's "run" /* Number of traps that happen between exec'ing the shell to run an
will attempts to start up the debugee under a shell. inferior and when we finally get to the inferior code, not counting
This is in order for argument-expansion to occur. E.g., the exec for the shell. This is 1 on most implementations.
(gdb) run * Overridden in nm.h files. */
The "*" gets expanded by the shell into a list of files.
While this is a nice feature, it turns out to interact badly
with some of the catch-fork/catch-exec features we have added.
In particular, if the shell does any fork/exec's before
the exec of the target program, that can confuse GDB.
To disable this feature, set STARTUP_WITH_SHELL to 0.
To enable this feature, set STARTUP_WITH_SHELL to 1.
The catch-exec traps expected during start-up will
be 1 if target is not started up with a shell, 2 if it is.
- RT
If you disable this, you need to decrement
START_INFERIOR_TRAPS_EXPECTED in tm.h. */
#define STARTUP_WITH_SHELL 1
#if !defined(START_INFERIOR_TRAPS_EXPECTED) #if !defined(START_INFERIOR_TRAPS_EXPECTED)
#define START_INFERIOR_TRAPS_EXPECTED 2 #define START_INFERIOR_TRAPS_EXPECTED 1
#endif #endif
struct private_inferior; struct private_inferior;

View File

@@ -4451,8 +4451,6 @@ procfs_init_inferior (struct target_ops *ops, int pid)
thread_change_ptid (pid_to_ptid (pid), thread_change_ptid (pid_to_ptid (pid),
ptid_build (pid, lwpid, 0)); ptid_build (pid, lwpid, 0));
/* Typically two, one trap to exec the shell, one to exec the
program being debugged. Defined by "inferior.h". */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED); startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
#ifdef SYS_syssgi #ifdef SYS_syssgi