public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Keith Seitz <keiths@redhat.com>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH 12/16] gdb/gdbserver: add a '--no-escape-args' command line option
Date: Sat, 20 Jan 2024 19:57:13 -0800	[thread overview]
Message-ID: <28c25e2d-4f33-49ba-9c3e-3b82c192ca93@redhat.com> (raw)
In-Reply-To: <47fe194ee2e88d8ed68192abc31ac8e3df626fe1.1704809585.git.aburgess@redhat.com>

[I realize the documentation has already been approved.
Nonetheles, I noticed some typos.]

On 1/9/24 06:26, Andrew Burgess wrote:
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 9dbe53384e1..abb07d74baf 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -898,9 +898,9 @@
>   ``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.
> +You can optionally have @code{@value{GDBP}} pass any arguments after
> +the executable file to the inferior using @code{--args} or
> +@code{--no-escape-args}.  These options stops option processing.
>   @smallexample
>   @value{GDBP} --args gcc -O2 -c foo.c
>   @end smallexample
> @@ -1246,6 +1246,56 @@
>   executable file are passed as command line arguments to the inferior.
>   This option stops option processing.
>   
> +Argument supplied using @code{--args} will have backslashes applied to

I think this should be "Arguments".

> +escape any special shell characters.  This ensures that when the
> +inferior starts it is passed arguments exactly as @value{GDBN}

and a comma is needed after the introductory phrase, "when the
inferior starts."

> +receives them.
> +
> +For example, consider the following command run under a shell:
> +@smallexample
> +@value{GDBP} --args ls *.c
> +@end smallexample
> +@noindent
> +In this case the shell will expand @kbd{*.c} at the time @value{GDBN}
> +is invoked, not at the time that the inferior is invoked.  As a
> +result, if an additional @kbd{.c} file is created after @value{GDBN}
> +is started, but before the inferior is started, then the inferior will
> +not show the file in its output; the list of matching files was
> +resolved at the time @value{GDBN} was started.
> +
> +If you quote the @kbd{*} character used in the @value{GDBN} command
> +line argument then this will prevent the shell that starts
> +@value{GDBN} from expanding the @kbd{*.c} pattern, however, this
> +quoting will also be passed to the shell that @value{GDBN} invokes in
> +order to start the inferior (@pxref{set startup-with-shell}), and this
> +will prevent the @kbd{*.c} pattern being expanded at this point either:
> +@smallexample
> +@value{GDBP} --args ls '*.c'
> +(@value{GDBP}) show args
> +Argument list to give program being debugged when it is started is "\*.log".

Is this supposed to be "\*.c"?

> +@end smallexample
> +@noindent
> +If this quoting behaviour does not meet your needs, then you could use
> +@code{--no-escape-args} instead, which is described below.
> +
> +@item --no-escape-args
> +@cindex @code{--no-escape-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.
> +
> +Unlike @code{--args}, arguments after the executable name will not
> +have any escaping applied to them.  As a result, any special shell
> +characters that are not expanded by the shell that invokes
> +@value{GDBN} will be expanded by the shell that @value{GDBN} uses to
> +start the inferior.
> +
> +@smallexample
> +@value{GDBP} --no-escape-args ls '*.c'
> +(@value{GDBP}) show args
> +Argument list to give program being debugged when it is started is "*.log".
> +@end smallexample
> +
>   @item -baud @var{bps}
>   @itemx -b @var{bps}
>   @cindex @code{--baud}
> @@ -50498,9 +50548,10 @@
>   directly to @code{stdout}, will also be made silent.
>   
>   @item --args @var{prog} [@var{arglist}]
> -Change interpretation of command line so that arguments following this
> -option are passed as arguments to the inferior.  As an example, take
> -the following command:
> +@itemx --no-escape-args @var{prog} [@var{arglist}]
> +Change interpretation of command line so that arguments following

"Change the"?

> +either of these options are passed as arguments to the inferior.  As
> +an example, take the following command:
>   
>   @smallexample
>   gdb ./a.out -q
> @@ -50515,7 +50566,44 @@
>   @end smallexample
>   
>   @noindent
> -starts @value{GDBN} with the introductory message, and passes the option to the inferior.
> +starts @value{GDBN} with the introductory message, and passes the
> +option @code{-q} to the inferior.
> +
> +The difference between @option{--args} and @option{--no-escape-args}
> +is whether @value{GDBN} applies escapes to the argument it sees:
> +
> +@smallexample
> +gdb --args ./a.out *.c
> +@end smallexample
> +
> +@noindent
> +in this case the @code{*.c} is expanded by the shell that invokes
> +@value{GDBN}, the list of matching files will be fixed in the inferior
> +argument list.  If instead this is used:
> +
> +@smallexample
> +gdb --args ./a.out '*.c'
> +@end smallexample
> +
> +@noindent
> +then the shell that invokes @value{GDBN} will not expand @code{*.c},
> +but instead @value{GDBN} will escape the @code{*} character so when
> +a.out is invoked it will be passed a literal @code{*.c}.  If instead
> +this is used:
> +
> +@smallexample
> +gdb --no-escape-args ./a.out '*.c'
> +@end smallexample
> +
> +@noindent
> +now @value{GDBN} will not escape the @code{*} character.  When the
> +inferior is invoked the @code{*.c} will be expanded, and the inferior
> +will be passed the list of files as present at the time the inferior
> +is invoked.
> +
> +This change of behaviour can be important if the list of matching
> +files could change between the time that @value{GDBN} is started, and
> +the time the inferior is started.
>   
>   @item --pid=@var{pid}
>   Attach @value{GDBN} to an already running program, with the PID @var{pid}.
> @@ -50857,6 +50945,18 @@
>   with the @option{--once} option, it will stop listening for any further
>   connection attempts after connecting to the first @value{GDBN} session.
>   
> +@item --no-escape-args
> +By default, inferior arguments passed on the @command{gdbserver}
> +command line will have any special shell characters escaped by
> +@command{gdbserver}.  This ensures that when @command{gdbserver}
> +invokes the inferior, the arguments passed to the inferior are
> +identical to the arguments passed to @command{gdbserver}.
> +
> +To disable this escaping, use @option{--no-escape-args}.  With this
> +option special shell characters will not be escaped.  When

Need a comma between "option" and "special."

Keith

> +@command{gdbserver} starts a new shell in order to invoke the
> +inferior, this new shell will expand any special shell characters.
> +
>   @c --disable-packet is not documented for users.
>   
>   @c --disable-randomization and --no-disable-randomization are superseded by
> diff --git a/gdb/main.c b/gdb/main.c
> index 015ed396f58..e9cd4172e4a 100644
> --- a/gdb/main.c
> +++ b/gdb/main.c
> @@ -622,9 +622,10 @@ captured_main_1 (struct captured_main_args *context)
>     char **argv = context->argv;
>   
>     static int quiet = 0;
> -  static int set_args = 0;
>     static int inhibit_home_gdbinit = 0;
>   
> +  enum { NO_ARGS, SET_ESC_ARGS, SET_NO_ESC_ARGS } set_args = NO_ARGS;
> +
>     /* Pointers to various arguments from command line.  */
>     char *symarg = NULL;
>     char *execarg = NULL;
> @@ -773,7 +774,9 @@ captured_main_1 (struct captured_main_args *context)
>         OPT_EIX,
>         OPT_EIEX,
>         OPT_READNOW,
> -      OPT_READNEVER
> +      OPT_READNEVER,
> +      OPT_SET_ESC_ARGS,
> +      OPT_SET_NO_ESC_ARGS,
>       };
>       /* This struct requires int* in the struct, but write_files is a bool.
>          So use this temporary int that we write back after argument parsing.  */
> @@ -846,7 +849,8 @@ captured_main_1 (struct captured_main_args *context)
>         {"windows", no_argument, NULL, OPT_WINDOWS},
>         {"statistics", no_argument, 0, OPT_STATISTICS},
>         {"write", no_argument, &write_files_1, 1},
> -      {"args", no_argument, &set_args, 1},
> +      {"args", no_argument, nullptr, OPT_SET_ESC_ARGS},
> +      {"no-escape-args", no_argument, nullptr, OPT_SET_NO_ESC_ARGS},
>         {"l", required_argument, 0, 'l'},
>         {"return-child-result", no_argument, &return_child_result, 1},
>         {0, no_argument, 0, 0}
> @@ -858,7 +862,7 @@ captured_main_1 (struct captured_main_args *context)
>   
>   	c = getopt_long_only (argc, argv, "",
>   			      long_options, &option_index);
> -	if (c == EOF || set_args)
> +	if (c == EOF || set_args != NO_ARGS)
>   	  break;
>   
>   	/* Long option that takes an argument.  */
> @@ -939,6 +943,12 @@ captured_main_1 (struct captured_main_args *context)
>   	  case OPT_EIEX:
>   	    cmdarg_vec.emplace_back (CMDARG_EARLYINIT_COMMAND, optarg);
>   	    break;
> +	  case OPT_SET_ESC_ARGS:
> +	    set_args = SET_ESC_ARGS;
> +	    break;
> +	  case OPT_SET_NO_ESC_ARGS:
> +	    set_args = SET_NO_ESC_ARGS;
> +	    break;
>   	  case 'B':
>   	    batch_flag = batch_silent = 1;
>   	    gdb_stdout = new null_file ();
> @@ -1072,7 +1082,7 @@ captured_main_1 (struct captured_main_args *context)
>   
>     /* Now that gdb_init has created the initial inferior, we're in
>        position to set args for that inferior.  */
> -  if (set_args)
> +  if (set_args != NO_ARGS)
>       {
>         /* The remaining options are the command-line options for the
>   	 inferior.  The first one is the sym/exec file, and the rest
> @@ -1084,8 +1094,11 @@ captured_main_1 (struct captured_main_args *context)
>         symarg = argv[optind];
>         execarg = argv[optind];
>         ++optind;
> +      escape_args_func escape_func
> +	= ((set_args == SET_ESC_ARGS) ? escape_shell_characters
> +	   : escape_quotes_and_white_space);
>         gdb::array_view<char * const> arg_view (&argv[optind], argc - optind);
> -      current_inferior ()->set_args (arg_view, escape_shell_characters);
> +      current_inferior ()->set_args (arg_view, escape_func);
>       }
>     else
>       {
> @@ -1398,7 +1411,8 @@ This is the GNU debugger.  Usage:\n\n\
>     gdb_puts (_("\
>   Selection of debuggee and its files:\n\n\
>     --args             Arguments after executable-file are passed to inferior.\n\
> -  --core=COREFILE    Analyze the core dump COREFILE.\n\
> +  --no-escape-args   Like --args, but arguments are not escaped.\n							\
> +  --core=COREFILE    Analyze the core dump COREFILE.\n	\
>     --exec=EXECFILE    Use EXECFILE as the executable.\n\
>     --pid=PID          Attach to running process PID.\n\
>     --directory=DIR    Search for source files in DIR.\n\
> diff --git a/gdb/testsuite/gdb.base/args.exp b/gdb/testsuite/gdb.base/args.exp
> index 7c123e36404..9ff9e7ee6d1 100644
> --- a/gdb/testsuite/gdb.base/args.exp
> +++ b/gdb/testsuite/gdb.base/args.exp
> @@ -32,41 +32,73 @@ if {[build_executable $testfile.exp $testfile $srcfile] == -1} {
>   # NAME is the name to use for the tests and ARGLIST is the list of
>   # arguments that are passed to GDB when it is started.
>   #
> -# The optional RE_LIST is the list of patterns to check the arguments
> -# against, these patterns should match ARGLIST.  If the arguments are
> -# expected to show up unmodified in the test output then RE_LIST can
> -# be dropped, and this proc will reuse ARGLIST.
> -
> -proc args_test { name arglist {re_list {}} } {
> -
> -    # If RE_LIST is not supplied then we can reuse ARGLIST, this
> -    # implies that the arguments will appear unmodified in the test
> -    # output.
> -    if {[llength $re_list] == 0} {
> -	set re_list $arglist
> +# The optional RE_ESC_LIST is the list of patterns to check the
> +# inferior arguments against when GDB is started using --args.  If
> +# RE_ESC_LIST is not given then ARGLIST is reused, this implies that
> +# the inferior arguments appear unchanged in the test output.
> +#
> +# The optional RE_NO_ESC_LIST is the list of patterns to check the
> +# inferior arguments against when GDB is started using
> +# --no-escape-args.  If RE_NO_ESC_LIST is not given then RE_ESC_LIST
> +# is reused, this implies that there's no difference between the test
> +# output when the arguments are escaped or not.
> +
> +proc args_test { name arglist {re_esc_list {}} {re_no_esc_list {}} } {
> +
> +    # If either of the two regexp lists are not specificed then we can
> +    # use an earlier argument value instead.
> +    #
> +    # For the first regexp list, if this is missing then we use the
> +    # argument list, this assumes that the arguments will appear
> +    # unmodified in the output.
> +    if {[llength $re_esc_list] == 0} {
> +	set re_esc_list $arglist
>       }
>   
> -    foreach_with_prefix startup_with_shell { on off } {
> -	save_vars { ::GDBFLAGS } {
> -	    set ::GDBFLAGS "$::GDBFLAGS --args $::binfile $arglist"
> -
> -	    clean_restart $::binfile
> -
> -	    gdb_test_no_output "set startup-with-shell ${startup_with_shell}" \
> -		"set startup-with-shell for $name"
> -
> -	    runto_main
> -	    gdb_breakpoint [gdb_get_line_number "set breakpoint here"]
> -	    gdb_continue_to_breakpoint "breakpoint for $name"
> -
> -	    set expected_len [expr 1 + [llength $re_list]]
> -	    gdb_test "print argc" "\\\$$::decimal = $expected_len" "argc for $name"
> +    # If the second regexp list is missing then we reuse the first
> +    # regexp list.  This assumes there's no difference between escaped
> +    # and unescaped arguments in the output.
> +    if {[llength $re_no_esc_list] == 0} {
> +	set re_no_esc_list $re_esc_list
> +    }
>   
> -	    set i 1
> -	    foreach arg $re_list {
> -		gdb_test "print argv\[$i\]" "\\\$$::decimal = $::hex \"$arg\"" \
> -		    "argv\[$i\] for $name"
> -		set i [expr $i + 1]
> +    foreach_with_prefix startup_with_shell { on off } {
> +	foreach_with_prefix arg_flag { args no-escape-args } {
> +	    save_vars { ::GDBFLAGS } {
> +		set ::GDBFLAGS "$::GDBFLAGS --${arg_flag} $::binfile $arglist"
> +
> +		clean_restart $::binfile
> +
> +		gdb_test_no_output \
> +		    "set startup-with-shell ${startup_with_shell}" \
> +		    "set startup-with-shell for $name"
> +
> +		runto_main
> +		gdb_breakpoint [gdb_get_line_number "set breakpoint here"]
> +		gdb_continue_to_breakpoint "breakpoint for $name"
> +
> +		if { $arg_flag eq "args" || $startup_with_shell eq "off" } {
> +		    set re_list $re_esc_list
> +		} else {
> +		    set re_list $re_no_esc_list
> +		}
> +
> +		set expected_len [expr 1 + [llength $re_list]]
> +		gdb_test "print argc" \
> +		    "\\\$$::decimal = $expected_len" "argc for $name"
> +
> +		set i 1
> +		foreach arg $re_list {
> +		    if { $arg eq "\n" } {
> +			set arg {\\n}
> +		    } elseif { $arg eq "\"" } {
> +			set arg {\\\"}
> +		    }
> +		    gdb_test "print argv\[$i\]" \
> +			"\\\$$::decimal = $::hex \"$arg\"" \
> +			"argv\[$i\] for $name"
> +		    set i [expr $i + 1]
> +		}
>   	    }
>   	}
>       }
> @@ -102,6 +134,11 @@ proc run_all_tests {} {
>       args_test "lone single quote" {{1} \' {3}}
>   
>       args_test "lone double quote" {{1} \" {3}} {1 \\\\\" 3}
> +
> +    save_vars { ::env(TEST) } {
> +	set ::env(TEST) "ABCD"
> +	args_test "shell variable" {{$TEST}} {\\$TEST} {{ABCD}}
> +    }
>   }
>   
>   run_all_tests
> diff --git a/gdb/testsuite/gdb.server/inferior-args.c b/gdb/testsuite/gdb.server/inferior-args.c
> new file mode 100644
> index 00000000000..5fd215f50a8
> --- /dev/null
> +++ b/gdb/testsuite/gdb.server/inferior-args.c
> @@ -0,0 +1,27 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2023 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include <stdio.h>
> +
> +int
> +main (int argc, char **argv)
> +{
> +  for (int i = 0; i < argc; i++)
> +    printf ("[%d] %s\n", i, argv[i]);
> +
> +  return 0;
> +}
> diff --git a/gdb/testsuite/gdb.server/inferior-args.exp b/gdb/testsuite/gdb.server/inferior-args.exp
> new file mode 100644
> index 00000000000..9b2aeb249e0
> --- /dev/null
> +++ b/gdb/testsuite/gdb.server/inferior-args.exp
> @@ -0,0 +1,157 @@
> +# Copyright 2023 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +
> +# Test passing inferior arguments on the gdbserver command line.  Tests the
> +# flags --no-startup-with-shell and --no-escape-args that change how GDB
> +# interprets the arguments being passed.
> +
> +# This test relies on starting gdbserver using the pipe syntax.  Not sure
> +# how well this will run if part of this test is being run elsewhere.
> +require {!is_remote target} {!is_remote host}
> +
> +load_lib gdbserver-support.exp
> +
> +standard_testfile
> +
> +require allow_gdbserver_tests
> +
> +set gdbserver [find_gdbserver]
> +if { $gdbserver == "" } {
> +    unsupported "could not find gdbserver"
> +    return
> +}
> +
> +standard_testfile
> +if {[build_executable "failed to prepare" $testfile $srcfile]} {
> +    return -1
> +}
> +
> +# EXTENDED_P is a boolean, when true gdbserver is started with --multi, and
> +# GDB connects using extended-remote protocol.  Otherwise, no --multi flag
> +# is passed, and GDB connects with the remote protocol.
> +#
> +# WITH_SHELL_P is a boolean, when true gdbserver starts the inferior using a
> +# shell, when false gdbserver is passed the --no-startup-with-shell command
> +# line option, and should not start the inferior through a shell.
> +#
> +# ESCAPE_P is a boolean, when true gdbserver applies escapes to the inferior
> +# arguments, when false gdbserver is passed the --no-escape-args command
> +# line option, and should not apply escaping to the inferior arguments.
> +#
> +# ARGLIST is a list of inferior arguments to add to the gdbserver command
> +# line.
> +#
> +# RE_LIST is a list of patterns to match, one for each of ARGLIST.  Once the
> +# inferior is started we check that each argument matches its corresponding
> +# entry in RE_LIST.
> +proc do_test_inner { extended_p with_shell_p escape_p arglist re_list } {
> +
> +    clean_restart ${::binfile}
> +
> +    gdb_test_no_output "set sysroot"
> +
> +    # Make sure we're disconnected, in case we're testing with an
> +    # extended-remote board, therefore already connected.
> +    gdb_test "disconnect" ".*"
> +
> +    if { $extended_p } {
> +	set protocol "extended-remote"
> +    } else {
> +	set protocol "remote"
> +    }
> +
> +    if { $escape_p } {
> +	set esc_opt ""
> +    } else {
> +	set esc_opt "--no-escape-args"
> +    }
> +
> +    if { $with_shell_p } {
> +	set shell_opt ""
> +    } else {
> +	set shell_opt "--no-startup-with-shell"
> +    }
> +
> +    gdb_test "target ${protocol} | ${::gdbserver} --once ${esc_opt} ${shell_opt} - ${::binfile} ${arglist}" \
> +	".*" \
> +	"start gdbserver over stdin"
> +
> +    gdb_breakpoint main
> +    gdb_continue_to_breakpoint main
> +
> +    set expected_len [expr 1 + [llength $re_list]]
> +    gdb_test "print argc" \
> +	"\\\$$::decimal = $expected_len" "check argc"
> +
> +    set i 1
> +    foreach arg $re_list {
> +	verbose -log "APB ($arg)"
> +	gdb_test "print argv\[$i\]" \
> +	    "\\\$$::decimal = $::hex \"$arg\"" \
> +	    "check argv\[$i\]"
> +	set i [expr $i + 1]
> +    }
> +}
> +
> +# Wrapper around do_test_inner.  NAME is the name of this test, used to make
> +# the test names unique.  ARGLIST is the list of inferior arguments to add
> +# to the gdbserver command line.
> +#
> +# The optional RE_ESC_LIST is a list of patterns to match against the
> +# inferior arguments once the inferior is started, one pattern for each
> +# argument.  If RE_ESC_LIST is not given then ARGLIST is reused, which
> +# implies the arguments appear unmodified in the test output.
> +#
> +# The optional RE_NO_ESC_LIST is a list of patterns ot match against the
> +# inferior arguments when gdbserver is started with --no-escape-args or
> +# --no-startup-with-shell.  There should be one pattern for each argument.
> +# If RE_NO_ESC_LIST is not given then RE_ESC_LIST is resused, which implies
> +# there's no difference in how the arguments are printed.
> +proc args_test { name arglist {re_esc_list {}} {re_no_esc_list {}} } {
> +    if {[llength $re_esc_list] == 0} {
> +	set re_esc_list $arglist
> +    }
> +
> +    if {[llength $re_no_esc_list] == 0} {
> +	set re_no_esc_list $re_esc_list
> +    }
> +
> +    foreach_with_prefix extended_p { yes no } {
> +	foreach_with_prefix startup_with_shell { on off } {
> +	    foreach_with_prefix escape_p { yes no } {
> +		if { $escape_p || !$startup_with_shell } {
> +		    set re_list $re_esc_list
> +		} else {
> +		    set re_list $re_no_esc_list
> +		}
> +
> +		with_test_prefix "$name" {
> +		    do_test_inner $extended_p $startup_with_shell \
> +			$escape_p $arglist $re_list
> +		}
> +	    }
> +	}
> +    }
> +}
> +
> +args_test "basic" {a b c}
> +args_test "one empty" {1 "" 3}
> +args_test "two empty" {1 "" "" 3}
> +args_test "one with single quotes" {1 "''" 3}
> +args_test "lone double quote" {"1" \" 3} {1 \\\\\" 3}
> +save_vars { env(TEST) } {
> +    set env(TEST) "ABCD"
> +    args_test "shell variable" {\$TEST} {\\$TEST} {ABCD}
> +}
> diff --git a/gdbserver/server.cc b/gdbserver/server.cc
> index 65df03ef309..0445fa0237f 100644
> --- a/gdbserver/server.cc
> +++ b/gdbserver/server.cc
> @@ -3837,10 +3837,20 @@ gdbserver_usage (FILE *stream)
>   	   "  --startup-with-shell\n"
>   	   "                        Start PROG using a shell.  I.e., execs a shell that\n"
>   	   "                        then execs PROG.  (default)\n"
> +	   "                        To make use of globbing and variable subsitution for\n"
> +	   "                        arguments passed directly on gdbserver invocation,\n"
> +	   "                        see the --no-escape-args command line option in\n"
> +	   "                        addition\n"
>   	   "  --no-startup-with-shell\n"
>   	   "                        Exec PROG directly instead of using a shell.\n"
> -	   "                        Disables argument globbing and variable substitution\n"
> -	   "                        on UNIX-like systems.\n"
> +	   "  --no-escape-args\n"
> +	   "                        If PROG is started using a shell (see the\n"
> +	   "                        --[no-]startup-with-shell option),\n"
> +	   "                        ARGS passed directly on gdbserver invocation are\n"
> +	   "                        escaped, so no globbing or variable substitution\n"
> +	   "                        happens for those. This option disables escaping, so\n"
> +	   "                        globbing and variable substituation in the shell\n"
> +	   "                        are done for ARGS on UNIX-like systems.\n"
>   	   "\n"
>   	   "Debug options:\n"
>   	   "\n"
> @@ -4074,6 +4084,7 @@ captured_main (int argc, char *argv[])
>     volatile int attach = 0;
>     int was_running;
>     bool selftest = false;
> +  bool escape_args = true;
>   #if GDB_SELF_TEST
>     std::vector<const char *> selftest_filters;
>   
> @@ -4230,6 +4241,8 @@ captured_main (int argc, char *argv[])
>   	startup_with_shell = true;
>         else if (strcmp (*next_arg, "--no-startup-with-shell") == 0)
>   	startup_with_shell = false;
> +      else if (strcmp (*next_arg, "--no-escape-args") == 0)
> +	escape_args = false;
>         else if (strcmp (*next_arg, "--once") == 0)
>   	run_once = true;
>         else if (strcmp (*next_arg, "--selftest") == 0)
> @@ -4339,8 +4352,10 @@ captured_main (int argc, char *argv[])
>         std::vector<char *> temp_arg_vector;
>         for (i = 1; i < n; i++)
>   	temp_arg_vector.push_back (next_arg[i]);
> +      escape_args_func escape_func = (escape_args ? escape_shell_characters
> +				      : escape_quotes_and_white_space);
>         program_args = construct_inferior_arguments (temp_arg_vector,
> -						   escape_shell_characters);
> +						   escape_func);
>   
>         /* Wait till we are at first instruction in program.  */
>         target_create_inferior (program_path.get (), program_args);


  parent reply	other threads:[~2024-01-21  3:57 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-09 14:26 [PATCH 00/16] Inferior argument (inc for remote targets) changes Andrew Burgess
2024-01-09 14:26 ` [PATCH 01/16] libiberty/buildargv: POSIX behaviour for backslash handling Andrew Burgess
2024-01-09 14:26 ` [PATCH 02/16] gdb/testsuite: add some xfail in gdb.base/startup-with-shell.exp Andrew Burgess
2024-01-09 14:26 ` [PATCH 03/16] gdb: Support some escaping of args with startup-with-shell being off Andrew Burgess
2024-01-09 14:26 ` [PATCH 04/16] gdb: remove the !startup_with_shell path from construct_inferior_arguments Andrew Burgess
2024-01-21  3:56   ` Keith Seitz
2024-01-09 14:26 ` [PATCH 05/16] gdbserver: convert program_args to a single string Andrew Burgess
2024-01-09 14:26 ` [PATCH 06/16] gdbsupport: have construct_inferior_arguments take an escape function Andrew Burgess
2024-01-09 14:26 ` [PATCH 07/16] gdbsupport: split escape_shell_characters in two Andrew Burgess
2024-01-09 14:26 ` [PATCH 08/16] gdb: move remote arg splitting and joining into gdbsupport/ Andrew Burgess
2024-01-21  3:57   ` Keith Seitz
2024-01-09 14:26 ` [PATCH 09/16] gdb/python: change escaping rules when setting arguments Andrew Burgess
2024-01-09 16:30   ` Eli Zaretskii
2024-01-09 14:26 ` [PATCH 10/16] gdb: add remote argument passing self tests Andrew Burgess
2024-01-21  3:57   ` Keith Seitz
2024-01-09 14:26 ` [PATCH 11/16] gdb/gdbserver: pass inferior arguments as a single string Andrew Burgess
2024-01-09 16:34   ` Eli Zaretskii
2024-01-09 16:35   ` Eli Zaretskii
2024-01-09 14:26 ` [PATCH 12/16] gdb/gdbserver: add a '--no-escape-args' command line option Andrew Burgess
2024-01-09 16:43   ` Eli Zaretskii
2024-01-21  3:57   ` Keith Seitz [this message]
2024-01-09 14:26 ` [PATCH 13/16] gdb: allow 'set args' and run commands to contain newlines Andrew Burgess
2024-01-09 16:44   ` Eli Zaretskii
2024-01-21  3:57   ` Keith Seitz
2024-01-09 14:26 ` [PATCH 14/16] gdb/gdbserver: remove some uses of free_vector_argv Andrew Burgess
2024-01-09 14:26 ` [PATCH 15/16] gdb: new maintenance command to help debug remote argument issues Andrew Burgess
2024-01-09 16:32   ` Eli Zaretskii
2024-01-21  3:57   ` Keith Seitz
2024-01-09 14:26 ` [PATCH 16/16] gdb/gdbserver: rework argument splitting and joining Andrew Burgess
2024-01-09 16:37   ` Eli Zaretskii
2024-01-21  3:57   ` Keith Seitz
2024-01-09 16:58 ` [PATCH 00/16] Inferior argument (inc for remote targets) changes Eli Zaretskii
2024-01-20 22:46   ` Andrew Burgess
2024-01-21 10:22     ` Eli Zaretskii
2024-01-22 10:29       ` Andrew Burgess
2024-01-10  8:28 ` Michael Weghorn
2024-01-21  3:56 ` Keith Seitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=28c25e2d-4f33-49ba-9c3e-3b82c192ca93@redhat.com \
    --to=keiths@redhat.com \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).