]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/gdbserver: move argument setting complexity into gdbsupport/
authorAndrew Burgess <aburgess@redhat.com>
Sun, 19 Nov 2023 15:24:59 +0000 (15:24 +0000)
committerAndrew Burgess <aburgess@redhat.com>
Fri, 13 Feb 2026 16:37:38 +0000 (16:37 +0000)
This commit removes some uses of gdb::argv_vec from GDB.

The gdb::argv_vec class exists in part due to our need to convert from
one container type to another in a few places, and I think by using
templates we can push this conversion down into
gdbsupport/common-inferior.{cc,h} and remove the conversion logic from
higher level code in GDB.  This should make core GDB simpler.

For examples of this simplification, see python/py-inferior.c,
remote.c, and unittests/remote-arg-selftests.c, where this commit has
allowed for the removal of some code that only exists in order to
convert the container type.

Ideally I'd like to see all uses of gdb::argv_vec removed, but I'm
still not sure about the use in nat/fork-inferior.c, I think its use
there might be the best solution, so for now at least, I have no plans
to touch that code.

There should be no user visible changes after this commit.

Approved-By: Tom Tromey <tom@tromey.com>
gdb/inferior.c
gdb/inferior.h
gdb/python/py-inferior.c
gdb/remote.c
gdb/unittests/remote-arg-selftests.c
gdbserver/server.cc
gdbsupport/common-inferior.cc
gdbsupport/common-inferior.h
gdbsupport/remote-args.cc
gdbsupport/remote-args.h

index 438ed9b7d7457ee8fb9cd5d7c9afc79f89f998ed..e050dec402e8f421710d721f0c1a290bd131c1a3 100644 (file)
@@ -165,15 +165,6 @@ inferior::tty ()
   return m_terminal;
 }
 
-/* See inferior.h.  */
-
-void
-inferior::set_args (gdb::array_view<char * const> args,
-                   bool escape_shell_char)
-{
-  set_args (construct_inferior_arguments (args, escape_shell_char));
-}
-
 void
 inferior::set_arch (gdbarch *arch)
 {
index 4df80a0ff970c86e837252bb42e2d454bdb0eaa9..a3d4842be2ce3e894988f9a7a4692bfc739b628c 100644 (file)
@@ -62,6 +62,7 @@ struct thread_info;
 #include "displaced-stepping.h"
 
 #include "gdbsupport/unordered_map.h"
+#include "gdbsupport/common-inferior.h"
 
 struct infcall_suspend_state;
 struct infcall_control_state;
@@ -545,7 +546,11 @@ public:
      ESCAPE_SHELL_CHAR is true all special shell characters in ARGS are
      escaped, When false only the characters that GDB sees as special will
      be escaped.  See construct_inferior_arguments for more details.  */
-  void set_args (gdb::array_view<char * const> args, bool escape_shell_char);
+  template<typename T>
+  void set_args (gdb::array_view<T const> args, bool escape_shell_char)
+  {
+    this->set_args (construct_inferior_arguments (args, escape_shell_char));
+  }
 
   /* Get the argument string to use when running this inferior.
 
index 69a7bfa3c37e4f4e10187f2d94938d6d01ae21bb..53f3344429d226c271353500d8c1da4c16f3c88b 100644 (file)
@@ -905,11 +905,8 @@ infpy_set_args (PyObject *self, PyObject *value, void *closure)
            return -1;
          args.push_back (std::move (str));
        }
-      std::vector<char *> argvec;
-      for (const auto &arg : args)
-       argvec.push_back (arg.get ());
-      gdb::array_view<char * const> view (argvec.data (), argvec.size ());
-      inf->inferior->set_args (view, true);
+      gdb::array_view<gdb::unique_xmalloc_ptr<char> const> args_view (args);
+      inf->inferior->set_args (args_view, true);
     }
   else
     {
index edabc2c9ee53cf6d43b77e33c250673d203b55f1..4ad595bda68d1e334ace85300157345d59c30d1a 100644 (file)
@@ -83,7 +83,6 @@
 #include "gdbsupport/selftest.h"
 #include "cli/cli-style.h"
 #include "gdbsupport/remote-args.h"
-#include "gdbsupport/gdb_argv_vec.h"
 #include "finish-thread-state.h"
 
 /* The remote target.  */
@@ -12761,21 +12760,13 @@ test_remote_args_command (const char *args, int from_tty)
   for (const std::string &a : split_args)
     gdb_printf ("  (%s)\n", a.c_str ());
 
-  gdb::argv_vec tmp_split_args;
-  for (const std::string &a : split_args)
-    tmp_split_args.emplace_back (xstrdup (a.c_str ()));
-
-  std::string joined_args = gdb::remote_args::join (tmp_split_args.get ());
+  std::string joined_args = gdb::remote_args::join (split_args);
 
   gdb_printf ("Output (%s)\n", joined_args.c_str ());
 
   std::vector<std::string> resplit = gdb::remote_args::split (joined_args);
 
-  tmp_split_args.clear ();
-  for (const std::string &a : resplit)
-    tmp_split_args.emplace_back (xstrdup (a.c_str ()));
-
-  std::string rejoined = gdb::remote_args::join (tmp_split_args.get ());
+  std::string rejoined = gdb::remote_args::join (resplit);
 
   if (joined_args != rejoined || split_args != resplit)
     {
index ec0678b46d84b8b5f909b891cd7a5fb6ed5969af..e878fefb2ef7488b29415d3d47a9c77d170494c3 100644 (file)
@@ -22,7 +22,6 @@
 #include "gdbsupport/buildargv.h"
 #include "gdbsupport/common-inferior.h"
 #include "gdbsupport/remote-args.h"
-#include "gdbsupport/gdb_argv_vec.h"
 
 namespace selftests {
 namespace remote_args_tests {
@@ -107,11 +106,8 @@ self_test ()
        }
 
       /* Now join the arguments.  */
-      gdb::argv_vec split_args_c_str;
-      for (const std::string &s : split_args)
-       split_args_c_str.push_back (xstrdup (s.c_str ()));
       std::string joined_args
-       = gdb::remote_args::join (split_args_c_str.get ());
+       = gdb::remote_args::join (split_args);
 
       if (run_verbose ())
        debug_printf ("Joined (%s), expected (%s)\n",
index 674300f8ce03a0da32939de12e8f4c8d8c521478..a7ecef3f5aa9b4c69a98ba738c7b1a6533a8c875 100644 (file)
@@ -49,7 +49,6 @@
 #include "gdbsupport/gdb_select.h"
 #include "gdbsupport/scoped_restore.h"
 #include "gdbsupport/search.h"
-#include "gdbsupport/gdb_argv_vec.h"
 #include "gdbsupport/remote-args.h"
 
 #include <getopt.h>
@@ -3442,7 +3441,7 @@ handle_v_run (char *own_buf)
 {
   client_state &cs = get_client_state ();
   char *p, *next_p;
-  gdb::argv_vec new_argv;
+  std::vector<gdb::unique_xmalloc_ptr<char>> new_argv;
   gdb::unique_xmalloc_ptr<char> new_program_name;
   int i;
 
@@ -3462,7 +3461,7 @@ handle_v_run (char *own_buf)
       else if (p == next_p)
        {
          /* Empty argument.  */
-         new_argv.push_back (xstrdup (""));
+         new_argv.push_back (make_unique_xstrdup (""));
        }
       else
        {
@@ -3479,7 +3478,7 @@ handle_v_run (char *own_buf)
          if (i == 0)
            new_program_name = std::move (arg);
          else
-           new_argv.push_back (arg.release ());
+           new_argv.push_back (std::move (arg));
        }
       if (*next_p == '\0')
        break;
@@ -3500,18 +3499,18 @@ handle_v_run (char *own_buf)
 
   if (cs.single_inferior_argument)
     {
-      if (new_argv.get ().size () > 1)
+      if (new_argv.size () > 1)
        {
          write_enn (own_buf);
          return;
        }
-      else if (new_argv.get ().size () == 1)
-       program_args = std::string (new_argv.get ()[0]);
+      else if (new_argv.size () == 1)
+       program_args = std::string (new_argv[0].get ());
       else
        program_args.clear ();
     }
   else
-    program_args = gdb::remote_args::join (new_argv.get ());
+    program_args = gdb::remote_args::join (new_argv);
 
   try
     {
@@ -4579,9 +4578,8 @@ captured_main (int argc, char *argv[])
        error (_("No program to debug"));
 
       int n = argc - (next_arg - argv);
-      program_args
-       = construct_inferior_arguments ({&next_arg[1], &next_arg[n]},
-                                       escape_args);
+      gdb::array_view<char * const> args_view (&next_arg[1], &next_arg[n]);
+      program_args = construct_inferior_arguments (args_view, escape_args);
 
       /* Wait till we are at first instruction in program.  */
       target_create_inferior (program_path.get (), program_args);
index 11b592100682147b485dbb8554c5fc1e173fc6ca..8134761ef738ddc078ef2f7e8c42b4283d6bc9ca 100644 (file)
@@ -130,10 +130,43 @@ escape_gdb_characters (const char * arg)
   return escape_characters (arg, special);
 }
 
-/* See common-inferior.h.  */
+/* Template function that converts a T to a 'const char *'.  */
+
+template<typename T> const char * to_char_ptr (T &arg);
+
+/* A no-op implementation that takes a 'const char *'.  */
+
+template<>
+const char *
+to_char_ptr (char * const &arg)
+{
+  return arg;
+}
+
+/* An implementation that gets a 'const char *' from a
+   gdb::unique_xmalloc_ptr<char> object.  */
+
+template<>
+const char *
+to_char_ptr (const gdb::unique_xmalloc_ptr<char> &arg)
+{
+  return arg.get ();
+}
+
+/* An implementation that gets a 'const char *' from a std::string.  */
+
+template<>
+const char *
+to_char_ptr (const std::string &arg)
+{
+  return arg.c_str ();
+}
+
+/* See gdbsupport/common-inferior.h.  */
 
+template<typename T>
 std::string
-construct_inferior_arguments (gdb::array_view<char * const> argv,
+construct_inferior_arguments (gdb::array_view<T const> argv,
                              bool escape_shell_char)
 {
   /* Select the desired escape function.  */
@@ -143,13 +176,35 @@ construct_inferior_arguments (gdb::array_view<char * const> argv,
 
   std::string result;
 
-  for (const char *a : argv)
+  for (const T &a : argv)
     {
       if (!result.empty ())
        result += " ";
 
-      result += escape_func (a);
+      result += escape_func (to_char_ptr (a));
     }
 
   return result;
 }
+
+/* Instantiate for T = 'gdb::unique_xmalloc_ptr<char>'.  */
+
+template
+std::string
+construct_inferior_arguments
+  (gdb::array_view<gdb::unique_xmalloc_ptr<char> const> argv,
+   bool escape_shell_char);
+
+/* Instantiate for T = 'char *'.  */
+
+template
+std::string
+construct_inferior_arguments (gdb::array_view<char * const> argv,
+                             bool escape_shell_char);
+
+/* Instantiate for T = 'std::string'.  */
+
+template
+std::string
+construct_inferior_arguments (gdb::array_view<std::string const> argv,
+                             bool escape_shell_char);
index b48f72ed152b23b54a40e4a8ec64e28ba4c8e19f..4645119e451adb77ab33cd145db1194aeadc35e0 100644 (file)
@@ -56,9 +56,14 @@ extern bool startup_with_shell;
    whitespace character between each element.  When ESCAPE_SHELL_CHAR is
    true then any special shell characters in elements of ARGV will be
    escaped.  When ESCAPE_SHELL_CHAR is false only the characters that GDB
-   sees as special (quotes and whitespace) are escaped.  */
+   sees as special (quotes and whitespace) are escaped.
+
+   This function is instantiated for T as 'gdb::unique_xmalloc_ptr<char>',
+   'char *', and 'std::string'.  */
+
+template<typename T>
 extern std::string
-construct_inferior_arguments (gdb::array_view<char * const> argv,
-                             bool escape_shell_char);
+construct_inferior_arguments
+       (gdb::array_view<T const> argv, bool escape_shell_char);
 
 #endif /* GDBSUPPORT_COMMON_INFERIOR_H */
index 3e8fc903f6f77981326f83b7eb1d5134e4bacde7..232adbff998ab5cf8faccea3c5f495bbfebfbd26 100644 (file)
@@ -33,11 +33,3 @@ gdb::remote_args::split (const std::string &args)
 
   return results;
 }
-
-/* See remote-args.h.  */
-
-std::string
-gdb::remote_args::join (const std::vector<char *> &args)
-{
-  return construct_inferior_arguments (args, true);
-}
index 2a925e889a4b3335ff011bceabdea5a164dfaca2..d714702a9b86165ff3803e6ec6cc11576427595e 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef GDBSUPPORT_REMOTE_ARGS_H
 #define GDBSUPPORT_REMOTE_ARGS_H
 
+#include "gdbsupport/common-inferior.h"
+
 /* The functions declared here are used when passing inferior arguments
    from GDB to gdbserver.
 
@@ -50,8 +52,18 @@ extern std::vector<std::string> split (const std::string &args);
    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 (const std::vector<char *> &args);
+   than wrap the argument in quotes.
+
+   This function depends on construct_inferior_arguments, which is
+   instantiated for the string types used within GDB, 'char *',
+   'std::string', and 'gdb::unique_xmalloc_ptr<char>'.  */
+
+template<typename T>
+inline std::string
+join (const std::vector<T> &args)
+{
+  return construct_inferior_arguments (gdb::array_view<const T> (args), true);
+}
 
 } /* namespace remote_args */