public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>,
	Michael Weghorn <m.weghorn@posteo.de>
Subject: [PATCH 08/16] gdb: move remote arg splitting and joining into gdbsupport/
Date: Tue,  9 Jan 2024 14:26:31 +0000	[thread overview]
Message-ID: <0b19b3f83eb1df36d1d4bfa2ccdb5ca9754f095f.1704809585.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1704809585.git.aburgess@redhat.com>

This is a refactoring commit.  When passing inferior arguments to
gdbserver we have two actions that need to be performed, splitting and
joining.

On the GDB side, we take the inferior arguments, a single string, and
split the string into a list of individual arguments.  These are then
sent to gdbserver over the remote protocol.

On the gdbserver side we receive the list of individual arguments and
join these back together into a single inferior argument string.

In a later commit I would like to add some unit testing for this
remote argument passing process.  Ideally, for unit testing, we want
to use the exact same code for splitting and joining the arguments as
is actually used -- we could duplicate the code within the unit test,
and this would validate the algorithm as it is today, but there is
always the risk that a future change would not be mirrored within the
tests, which makes the tests useless.

So in this commit I propose to move the splitting and joining logic
out into a separate file, we can then use this within GDB and
gdbserver when passing arguments between GDB and gdbserver, but we can
also use the exact same code for some unit tests.

In this commit I'm not adding the unit tests, they will be added later
in this series, so for now there should be no user visible changes
after this commit.
---
 gdb/remote.c              | 12 +++++------
 gdbserver/server.cc       |  4 ++--
 gdbsupport/Makefile.am    |  1 +
 gdbsupport/Makefile.in    | 13 +++++++-----
 gdbsupport/remote-args.cc | 43 ++++++++++++++++++++++++++++++++++++++
 gdbsupport/remote-args.h  | 44 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 104 insertions(+), 13 deletions(-)
 create mode 100644 gdbsupport/remote-args.cc
 create mode 100644 gdbsupport/remote-args.h

diff --git a/gdb/remote.c b/gdb/remote.c
index dcc1a0d0639..ebef409ffed 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -79,6 +79,7 @@
 #include <unordered_map>
 #include "async-event.h"
 #include "gdbsupport/selftest.h"
+#include "gdbsupport/remote-args.h"
 
 /* The remote target.  */
 
@@ -10625,16 +10626,15 @@ remote_target::extended_remote_run (const std::string &args)
 
   if (!args.empty ())
     {
-      int i;
+      std::vector<std::string> split_args = gdb::remote_args::split (args);
 
-      gdb_argv argv (args.c_str ());
-      for (i = 0; argv[i] != NULL; i++)
+      for (const auto &a : split_args)
 	{
-	  if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ())
+	  if (a.size () * 2 + 1 + len >= get_remote_packet_size ())
 	    error (_("Argument list too long for run packet"));
 	  rs->buf[len++] = ';';
-	  len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf.data () + len,
-			      strlen (argv[i]));
+	  len += 2 * bin2hex ((gdb_byte *) a.c_str (), rs->buf.data () + len,
+			      a.size ());
 	}
     }
 
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 52ce9240ca3..13abb0b7636 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -51,6 +51,7 @@
 #include "gdbsupport/gdb_select.h"
 #include "gdbsupport/scoped_restore.h"
 #include "gdbsupport/search.h"
+#include "gdbsupport/remote-args.h"
 
 /* PBUFSIZ must also be at least as big as IPA_CMD_BUF_SIZE, because
    the client state data is passed directly to some agent
@@ -3437,8 +3438,7 @@ handle_v_run (char *own_buf)
   else
     program_path.set (new_program_name.get ());
 
-  program_args = construct_inferior_arguments (new_argv,
-					       escape_shell_characters);
+  program_args = gdb::remote_args::join (new_argv);
   free_vector_argv (new_argv);
 
   target_create_inferior (program_path.get (), program_args);
diff --git a/gdbsupport/Makefile.am b/gdbsupport/Makefile.am
index f1a641308fe..6f5a5ef36c6 100644
--- a/gdbsupport/Makefile.am
+++ b/gdbsupport/Makefile.am
@@ -72,6 +72,7 @@ libgdbsupport_a_SOURCES = \
     pathstuff.cc \
     print-utils.cc \
     ptid.cc \
+    remote-args.cc \
     rsp-low.cc \
     run-time-clock.cc \
     safe-strerror.cc \
diff --git a/gdbsupport/Makefile.in b/gdbsupport/Makefile.in
index 9fdc23c39a9..5d860302baa 100644
--- a/gdbsupport/Makefile.in
+++ b/gdbsupport/Makefile.in
@@ -163,11 +163,12 @@ am_libgdbsupport_a_OBJECTS = agent.$(OBJEXT) btrace-common.$(OBJEXT) \
 	gdb_tilde_expand.$(OBJEXT) gdb_wait.$(OBJEXT) \
 	gdb_vecs.$(OBJEXT) job-control.$(OBJEXT) netstuff.$(OBJEXT) \
 	new-op.$(OBJEXT) pathstuff.$(OBJEXT) print-utils.$(OBJEXT) \
-	ptid.$(OBJEXT) rsp-low.$(OBJEXT) run-time-clock.$(OBJEXT) \
-	safe-strerror.$(OBJEXT) scoped_mmap.$(OBJEXT) search.$(OBJEXT) \
-	signals.$(OBJEXT) signals-state-save-restore.$(OBJEXT) \
-	tdesc.$(OBJEXT) thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) \
-	$(am__objects_1) $(am__objects_2)
+	ptid.$(OBJEXT) remote-args.$(OBJEXT) rsp-low.$(OBJEXT) \
+	run-time-clock.$(OBJEXT) safe-strerror.$(OBJEXT) \
+	scoped_mmap.$(OBJEXT) search.$(OBJEXT) signals.$(OBJEXT) \
+	signals-state-save-restore.$(OBJEXT) tdesc.$(OBJEXT) \
+	thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) $(am__objects_1) \
+	$(am__objects_2)
 libgdbsupport_a_OBJECTS = $(am_libgdbsupport_a_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -429,6 +430,7 @@ libgdbsupport_a_SOURCES = \
     pathstuff.cc \
     print-utils.cc \
     ptid.cc \
+    remote-args.cc \
     rsp-low.cc \
     run-time-clock.cc \
     safe-strerror.cc \
@@ -538,6 +540,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pathstuff.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print-utils.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remote-args.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsp-low.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-time-clock.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe-strerror.Po@am__quote@
diff --git a/gdbsupport/remote-args.cc b/gdbsupport/remote-args.cc
new file mode 100644
index 00000000000..96c12ffac67
--- /dev/null
+++ b/gdbsupport/remote-args.cc
@@ -0,0 +1,43 @@
+/* Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 "gdbsupport/common-defs.h"
+#include "gdbsupport/remote-args.h"
+#include "gdbsupport/common-inferior.h"
+#include "gdbsupport/buildargv.h"
+
+/* See remote-args.h.  */
+
+std::vector<std::string>
+gdb::remote_args::split (std::string args)
+{
+  std::vector<std::string> results;
+
+  gdb_argv argv (args.c_str ());
+  for (int i = 0; argv[i] != nullptr; i++)
+    results.emplace_back (argv[i]);
+
+  return results;
+}
+
+/* See remote-args.h.  */
+
+std::string
+gdb::remote_args::join (std::vector<char *> &args)
+{
+  return construct_inferior_arguments (args, escape_shell_characters);
+}
diff --git a/gdbsupport/remote-args.h b/gdbsupport/remote-args.h
new file mode 100644
index 00000000000..c0acce9b7c4
--- /dev/null
+++ b/gdbsupport/remote-args.h
@@ -0,0 +1,44 @@
+/* Functions to help when passing arguments between GDB and gdbserver.
+
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+namespace gdb
+{
+
+namespace remote_args
+{
+
+/* ARGS is an inferior argument string.  This function splits ARGS into
+   individual arguments and returns a vector containing each argument.  */
+
+extern std::vector<std::string> split (std::string args);
+
+/* Join together the separate arguments in ARGS and build a single
+   inferior argument string.  The string returned by this function will be
+   equivalent, but not necessarily identical to the string passed to
+   ::split, for example passing the string '"a b"' (without the single
+   quotes, but including the double quotes) to ::split, will return an
+   argument of 'a b' (without the single quotes).  When this argument is
+   passed through ::join we will get back the string 'a\ b' (without the
+   single quotes), that is, we choose to escape the white space, rather
+   than wrap the argument in quotes.  */
+extern std::string join (std::vector<char *> &args);
+
+} /* namespace remote_args */
+
+} /* namespac gdb */
-- 
2.25.4


  parent reply	other threads:[~2024-01-09 14:26 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 ` Andrew Burgess [this message]
2024-01-21  3:57   ` [PATCH 08/16] gdb: move remote arg splitting and joining into gdbsupport/ 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
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=0b19b3f83eb1df36d1d4bfa2ccdb5ca9754f095f.1704809585.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=m.weghorn@posteo.de \
    /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).