diff --git a/gdb/NEWS b/gdb/NEWS index 1a9cd9df897..1daddd059eb 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -6,6 +6,14 @@ * Support for .gdb_index sections with version less than 7 has been removed. +* GDB now accepts --no-escape-args as an alternative to --args on the + command line. GDB will not escape special shell characters within + arguments after --no-escape-args. + +* gdbserver now accepts --no-escape-args as a command line flag. When + this flag is used gdbserver will not escape special shell characters + within the inferior arguments. + * New targets GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux* diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index dd9498c3dc8..f8154212fa4 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -898,14 +898,17 @@ debugger attached to a bare board, there may not be any notion of ``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 stop option processing. @smallexample @value{GDBP} --args gcc -O2 -c foo.c @end smallexample This will cause @code{@value{GDBP}} to debug @code{gcc}, and to set -@code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 -c foo.c}. +@code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 +-c foo.c}. For the differences between @code{--args} and +@code{--no-escape-args}, see @ref{--args and --no-escape-args options, +,@code{--args} and @code{--no-escape-args}}. You can run @code{@value{GDBP}} without printing the front material, which describes @value{GDBN}'s non-warranty, by specifying @code{--silent} @@ -1240,12 +1243,67 @@ that control @value{GDBN}, and level 2 has been deprecated. The annotation mechanism has largely been superseded by @sc{gdb/mi} (@pxref{GDB/MI}). +@anchor{--args and --no-escape-args options} @item --args @cindex @code{--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. +Arguments supplied using @code{--args} will have backslashes applied +to escape any special shell characters. This ensures that when the +inferior starts it is passed arguments exactly as @value{GDBN} +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 on 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". +@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} @@ -51236,9 +51294,10 @@ Note that targets that give their output via @value{GDBN}, as opposed to writing 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 +either of these options are passed as arguments to the inferior. As +an example, take the following command: @smallexample gdb ./a.out -q @@ -51253,7 +51312,44 @@ gdb --args ./a.out -q @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 arguments 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}, +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}. @@ -51595,6 +51691,18 @@ additional connections are possible. However, if you start @code{gdbserver} 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 +@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 e1ef537c357..04c33638bec 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -617,9 +617,20 @@ 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; + /* Has the user passed inferior arguments on the command line. */ + enum { + /* No arguments passed. */ + NO_ARGS, + + /* Arguments passed with --args. */ + SET_ESC_ARGS, + + /* Arguments passed with --no-escape-args. */ + SET_NO_ESC_ARGS + } set_args = NO_ARGS; + /* Pointers to various arguments from command line. */ char *symarg = NULL; char *execarg = NULL; @@ -769,7 +780,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. */ @@ -842,7 +855,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} @@ -854,7 +868,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. */ @@ -935,6 +949,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 (); @@ -1068,7 +1088,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 @@ -1080,10 +1100,9 @@ captured_main_1 (struct captured_main_args *context) symarg = argv[optind]; execarg = argv[optind]; ++optind; - current_inferior ()->set_args - (gdb::array_view (&argv[optind], argc - optind), - startup_with_shell); - } + gdb::array_view arg_view (&argv[optind], argc - optind); + current_inferior ()->set_args (arg_view, (set_args == SET_ESC_ARGS)); + } else { /* OK, that's all the options. */ @@ -1400,7 +1419,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 36bfee2fa4b..b8596608439 100644 --- a/gdb/testsuite/gdb.base/args.exp +++ b/gdb/testsuite/gdb.base/args.exp @@ -33,42 +33,87 @@ 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. +# 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_list {}} } { +proc args_test { name arglist {re_esc_list {}} {re_no_esc_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 + # 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 + } + + # 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 } foreach_with_prefix startup_with_shell { on off } { - save_vars { ::GDBFLAGS } { - set ::GDBFLAGS "$::GDBFLAGS --args $::binfile $arglist" + foreach_with_prefix arg_flag { args no-escape-args } { + save_vars { ::GDBFLAGS } { + set ::GDBFLAGS "$::GDBFLAGS --${arg_flag} $::binfile $arglist" - clean_restart - gdb_load $::binfile + clean_restart $::testfile - gdb_test_no_output "set startup-with-shell ${startup_with_shell}" \ - "set startup-with-shell for $name" + 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" + 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 { $arg_flag eq "args" || $startup_with_shell eq "off" } { + set re_list $re_esc_list + } else { + set re_list $re_no_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] + 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 {\\\"} + } + + # If we are starting with a shell, we're not escaping + # special shell characters in arguments passed to GDB, + # we're using a remote target, and the arguments contain + # a shell variable (indicated with a '$'), then this + # test will currently fail if we are splitting the + # arguments. + if { $startup_with_shell eq "on" + && $arg_flag eq "no-escape-args" + && [gdb_protocol_is_remote] + && [string first "\$" $arglist] != -1 } { + setup_xfail "*-*-*" gdb/28392 + } + + gdb_test "print argv\[$i\]" \ + "\\\$$::decimal = $::hex \"$arg\"" \ + "argv\[$i\] for $name" + set i [expr $i + 1] + } } } } @@ -102,3 +147,8 @@ args_test "two newlines" {{1} "\n" "\n" {3}} {1 \\\\n \\\\n 3} 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}} +} diff --git a/gdb/testsuite/gdb.server/inferior-args.c b/gdb/testsuite/gdb.server/inferior-args.c new file mode 100644 index 00000000000..3bc3ff7628f --- /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-2025 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 . */ + +#include + +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..2ee26c5d193 --- /dev/null +++ b/gdb/testsuite/gdb.server/inferior-args.exp @@ -0,0 +1,156 @@ +# Copyright 2023-2025 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 . + +# 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 ${::testfile} + + 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 { + 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 6dc805abd4d..1f910a415b6 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -3851,10 +3851,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" @@ -4110,6 +4120,7 @@ captured_main (int argc, char *argv[]) volatile bool multi_mode = false; volatile bool attach = false; bool selftest = false; + bool escape_args = true; #if GDB_SELF_TEST std::vector selftest_filters; @@ -4132,7 +4143,7 @@ captured_main (int argc, char *argv[]) OPT_DEBUG, OPT_DEBUG_FILE, OPT_DEBUG_FORMAT, OPT_DISABLE_PACKET, OPT_DISABLE_RANDOMIZATION, OPT_NO_DISABLE_RANDOMIZATION, OPT_STARTUP_WITH_SHELL, OPT_NO_STARTUP_WITH_SHELL, OPT_ONCE, - OPT_SELFTEST, + OPT_SELFTEST, OPT_NO_ESCAPE }; static struct option longopts[] = @@ -4157,6 +4168,7 @@ captured_main (int argc, char *argv[]) OPT_NO_STARTUP_WITH_SHELL}, {"once", no_argument, nullptr, OPT_ONCE}, {"selftest", optional_argument, nullptr, OPT_SELFTEST}, + {"no-escape-args", no_argument, nullptr, OPT_NO_ESCAPE}, {nullptr, no_argument, nullptr, 0} }; @@ -4360,6 +4372,10 @@ captured_main (int argc, char *argv[]) } break; + case OPT_NO_ESCAPE: + escape_args = false; + break; + case '?': /* Figuring out which element of ARGV contained the invalid argument is not simple. There are a couple of cases we need @@ -4475,7 +4491,8 @@ captured_main (int argc, char *argv[]) int n = argc - (next_arg - argv); program_args - = construct_inferior_arguments ({&next_arg[1], &next_arg[n]}, true); + = construct_inferior_arguments ({&next_arg[1], &next_arg[n]}, + escape_args); /* Wait till we are at first instruction in program. */ target_create_inferior (program_path.get (), program_args);