gdbserver cannot handle program arguments containing space, but splits such arguments into separate ones. # Steps to reproduce: 1) compile small sample program ("test.cxx") given below: g++ -g -O0 -o test test.cxx 2) run with gdbserver, passing an arg containing space gdbserver localhost:50505 test "hello world" 3) attach with GDB, and inspect the program arguments: (gdb) target remote localhost:50505 [...] (gdb) break main Breakpoint 1 at 0x555555555174: file test.cxx, line 3. (gdb) c Continuing. [...] Breakpoint 1, main (argc=3, argv=0x7fffffffddf8) at test.cxx:3 3 std::cout << argv[1] << std::endl; (gdb) p argc $1 = 3 (gdb) p argv[1] $2 = 0x7fffffffe1a6 "hello" (gdb) p argv[2] $3 = 0x7fffffffe1ac "world" (gdb) # Actual result: Instead of showing a single argument "hello world", two separate arguments ("hello", "world") are shown. # Expected result: A single argument "hello world" should have been passed to the program, as is the case when using "plain" gdb instead of gdbserver: $ gdb --args test "hello world" [...] (gdb) break main Breakpoint 1 at 0x1174: file test.cxx, line 3. (gdb) r Starting program: /home/michi/temp/2020-04-24_gdb_gdbserver_args/test hello\ world Breakpoint 1, main (argc=2, argv=0x7fffffffddd8) at test.cxx:3 3 std::cout << argv[1] << std::endl; (gdb) p argc $1 = 2 (gdb) p argv[1] $2 = 0x7fffffffe197 "hello world" # Further notes I initially experienced this bug with gdb version 9.1 in Debian testing (amd64), but it's also reproducible with current git master, as of commit 0b2f8a3bbb595a99dd7977caa6382aab25630115. I plan to submit patches that show a potential approach to fix this. # Sample program "test.cxx": #include <iostream> int main(int argc, char** argv) { std::cout << argv[1] << std::endl; return 0; }
I've sent patches with a potential solution to the gdb-patches mailing list, thread starts at https://sourceware.org/pipermail/gdb-patches/2020-April/168037.html
The master branch has been updated by Simon Marchi <simark@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bea571ebd78ee29cb94adf648fbcda1e109e1be6 commit bea571ebd78ee29cb94adf648fbcda1e109e1be6 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Mon May 25 11:39:43 2020 -0400 Use construct_inferior_arguments which handles special chars Use the construct_inferior_arguments function instead of stringify_argv to construct a string from the program arguments in those places where that one is then passed to fork_inferior (linux-low, lyn-low), since construct_inferior_arguments properly takes care of special characters, while stringify_argv does not. Using construct_inferior_arguments seems "natural", since its documentation also mentions that it "does the same shell processing as fork_inferior". Since construct_inferior_args has been extended to do proper quoting for Windows shells in commit 5d60742e2dd3c9b475dce54b56043a358751bbb8 ("Fix quoting of special characters for the MinGW build.", 2012-06-12), use it for the Windows case as well. (I could not test that case myself, though.) Adapt handling of empty args in function 'handle_v_run' in gdbserver/server.cc to just insert an empty string for an empty arg, since that one is now properly handled in 'construct_inferior_arguments' already (and inserting a "''" string in 'handle_v_run' would otherwise cause that one to be treated as a string literally containing two quote characters, which 'construct_inferior_args' would preserve by adding extra escaping). This makes gdbserver properly handle program args containing special characters (like spaces), e.g. (example from PR25893) $ gdbserver localhost:50505 myprogram "hello world" now properly handles "hello world" as a single arg, not two separate ones ("hello", "world"). gdbserver/ChangeLog: PR gdbserver/25893 * linux-low.cc (linux_process_target::create_inferior), lynx-low.cc (lynx_process_target::create_inferior), win32-low.cc (win32_process_target::create_inferior): Use construct_inferior_arguments instead of stringify_argv to get string representation which properly escapes special characters. * server.cc (handle_v_run): Just pass empty program arg as such, since any further processing is now handled via construct_inferior_arguments. Change-Id: Ibf963fcd51415c948840fb463289516b3479b0c3
Fixed.