From: Andrew Burgess Date: Sun, 19 Nov 2023 15:24:59 +0000 (+0000) Subject: gdb/gdbserver: move argument setting complexity into gdbsupport/ X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7de2cbde437a37aae1b8eb8da7718e5179187dda;p=thirdparty%2Fbinutils-gdb.git gdb/gdbserver: move argument setting complexity into gdbsupport/ 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 --- diff --git a/gdb/inferior.c b/gdb/inferior.c index 438ed9b7d74..e050dec402e 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -165,15 +165,6 @@ inferior::tty () return m_terminal; } -/* See inferior.h. */ - -void -inferior::set_args (gdb::array_view args, - bool escape_shell_char) -{ - set_args (construct_inferior_arguments (args, escape_shell_char)); -} - void inferior::set_arch (gdbarch *arch) { diff --git a/gdb/inferior.h b/gdb/inferior.h index 4df80a0ff97..a3d4842be2c 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -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 args, bool escape_shell_char); + template + void set_args (gdb::array_view 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. diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 69a7bfa3c37..53f3344429d 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -905,11 +905,8 @@ infpy_set_args (PyObject *self, PyObject *value, void *closure) return -1; args.push_back (std::move (str)); } - std::vector argvec; - for (const auto &arg : args) - argvec.push_back (arg.get ()); - gdb::array_view view (argvec.data (), argvec.size ()); - inf->inferior->set_args (view, true); + gdb::array_view const> args_view (args); + inf->inferior->set_args (args_view, true); } else { diff --git a/gdb/remote.c b/gdb/remote.c index edabc2c9ee5..4ad595bda68 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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 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) { diff --git a/gdb/unittests/remote-arg-selftests.c b/gdb/unittests/remote-arg-selftests.c index ec0678b46d8..e878fefb2ef 100644 --- a/gdb/unittests/remote-arg-selftests.c +++ b/gdb/unittests/remote-arg-selftests.c @@ -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", diff --git a/gdbserver/server.cc b/gdbserver/server.cc index 674300f8ce0..a7ecef3f5aa 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -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 @@ -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> new_argv; gdb::unique_xmalloc_ptr 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 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); diff --git a/gdbsupport/common-inferior.cc b/gdbsupport/common-inferior.cc index 11b59210068..8134761ef73 100644 --- a/gdbsupport/common-inferior.cc +++ b/gdbsupport/common-inferior.cc @@ -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 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 object. */ + +template<> +const char * +to_char_ptr (const gdb::unique_xmalloc_ptr &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 std::string -construct_inferior_arguments (gdb::array_view argv, +construct_inferior_arguments (gdb::array_view argv, bool escape_shell_char) { /* Select the desired escape function. */ @@ -143,13 +176,35 @@ construct_inferior_arguments (gdb::array_view 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'. */ + +template +std::string +construct_inferior_arguments + (gdb::array_view const> argv, + bool escape_shell_char); + +/* Instantiate for T = 'char *'. */ + +template +std::string +construct_inferior_arguments (gdb::array_view argv, + bool escape_shell_char); + +/* Instantiate for T = 'std::string'. */ + +template +std::string +construct_inferior_arguments (gdb::array_view argv, + bool escape_shell_char); diff --git a/gdbsupport/common-inferior.h b/gdbsupport/common-inferior.h index b48f72ed152..4645119e451 100644 --- a/gdbsupport/common-inferior.h +++ b/gdbsupport/common-inferior.h @@ -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 *', and 'std::string'. */ + +template extern std::string -construct_inferior_arguments (gdb::array_view argv, - bool escape_shell_char); +construct_inferior_arguments + (gdb::array_view argv, bool escape_shell_char); #endif /* GDBSUPPORT_COMMON_INFERIOR_H */ diff --git a/gdbsupport/remote-args.cc b/gdbsupport/remote-args.cc index 3e8fc903f6f..232adbff998 100644 --- a/gdbsupport/remote-args.cc +++ b/gdbsupport/remote-args.cc @@ -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 &args) -{ - return construct_inferior_arguments (args, true); -} diff --git a/gdbsupport/remote-args.h b/gdbsupport/remote-args.h index 2a925e889a4..d714702a9b8 100644 --- a/gdbsupport/remote-args.h +++ b/gdbsupport/remote-args.h @@ -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 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 &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'. */ + +template +inline std::string +join (const std::vector &args) +{ + return construct_inferior_arguments (gdb::array_view (args), true); +} } /* namespace remote_args */