diff --git a/gdb/NEWS b/gdb/NEWS
index 65a082808e4..80c766eeeda 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -9,6 +9,14 @@
 * GDB index now contains information about the main function.  This speeds up
   startup when it is being used for some large binaries.
 
+* 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.
+
 * Changed commands
 
 disassemble
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
+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 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".
+@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
+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
+@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);
