aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdbserver/server.cc8
-rw-r--r--gdbsupport/gdb_argv_vec.h139
2 files changed, 142 insertions, 5 deletions
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 0ad27d5..33ff847 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -50,6 +50,7 @@
#include "gdbsupport/gdb_select.h"
#include "gdbsupport/scoped_restore.h"
#include "gdbsupport/search.h"
+#include "gdbsupport/gdb_argv_vec.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
@@ -3404,7 +3405,7 @@ handle_v_run (char *own_buf)
{
client_state &cs = get_client_state ();
char *p, *next_p;
- std::vector<char *> new_argv;
+ gdb::argv_vec new_argv;
gdb::unique_xmalloc_ptr<char> new_program_name;
int i;
@@ -3435,7 +3436,6 @@ handle_v_run (char *own_buf)
if (arg == nullptr)
{
write_enn (own_buf);
- free_vector_argv (new_argv);
return;
}
@@ -3455,15 +3455,13 @@ handle_v_run (char *own_buf)
if (program_path.get () == nullptr)
{
write_enn (own_buf);
- free_vector_argv (new_argv);
return;
}
}
else
program_path.set (new_program_name.get ());
- program_args = construct_inferior_arguments (new_argv);
- free_vector_argv (new_argv);
+ program_args = construct_inferior_arguments (new_argv.get ());
try
{
diff --git a/gdbsupport/gdb_argv_vec.h b/gdbsupport/gdb_argv_vec.h
new file mode 100644
index 0000000..1f3b6db
--- /dev/null
+++ b/gdbsupport/gdb_argv_vec.h
@@ -0,0 +1,139 @@
+/* Wrap std::vector<char *> that owns the 'char *' strings.
+
+ Copyright (C) 2025 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/>. */
+
+#ifndef GDBSUPPORT_GDB_ARGV_VEC_H
+#define GDBSUPPORT_GDB_ARGV_VEC_H
+
+#include "gdbsupport/common-utils.h"
+#include <vector>
+
+namespace gdb
+{
+
+/* A class that wraps around a vector of 'char *' strings. The class owns
+ the strings within the vector and will release them by calling xfree()
+ on each string when this classes destructor is called. */
+class argv_vec final
+{
+ /* Vector of strings. This class owns the strings within the vector.
+ This is at the start of the class so we can use decltype(). */
+ std::vector<char *> m_args;
+
+public:
+
+ using value_type = decltype (m_args)::value_type;
+ using iterator = decltype (m_args)::iterator;
+ using const_iterator = decltype (m_args)::const_iterator;
+ using reference = decltype (m_args)::reference;
+ using const_reference = decltype (m_args)::const_reference;
+
+ argv_vec ()
+ {
+ /* Nothing. */
+ }
+
+ /* Move the owned strings from OTHER. */
+ argv_vec (argv_vec &&other)
+ {
+ this->m_args = std::move (other.m_args);
+ }
+
+ /* Don't currently support copying the strings from OTHER. */
+ argv_vec (const argv_vec &other) = delete;
+
+ /* Move elements from OTHER. Free currently owned strings. */
+ argv_vec &operator= (argv_vec &&other)
+ {
+ free_vector_argv (m_args);
+ this->m_args = std::move (other.m_args);
+ return *this;
+ }
+
+ /* Don't currently support copying the strings from OTHER. */
+ argv_vec &operator= (const argv_vec &other) = delete;
+
+ /* Release the owned strings. */
+ ~argv_vec ()
+ {
+ free_vector_argv (m_args);
+ }
+
+ /* Append VALUE to the end of m_args. This class takes ownership of
+ VALUE, and will release VALUE by calling xfree() on it when this
+ object is destroyed. */
+ void push_back (const value_type &value)
+ {
+ m_args.push_back (value);
+ }
+
+ /* Append VALUE to the end of m_args. This class takes ownership of
+ VALUE, and will release VALUE by calling xfree() on it when this
+ object is destroyed. */
+ void push_back (value_type &&value)
+ {
+ m_args.push_back (value);
+ }
+
+ /* Non constant iterator to start of m_args. */
+ iterator begin ()
+ {
+ return m_args.begin ();
+ }
+
+ /* Non constant iterator to end of m_args. */
+ iterator end ()
+ {
+ return m_args.end ();
+ }
+
+ /* Constant iterator to start of m_args. */
+ const_iterator begin () const
+ {
+ return m_args.begin ();
+ }
+
+ /* Constant iterator to end of m_args. */
+ const_iterator end () const
+ {
+ return m_args.end ();
+ }
+
+ /* Return contiguous block of 'char *' pointers. Ideally this would be
+ const, but the execve interface to which this data is passed doesn't
+ accept 'const char **'. */
+ char **argv ()
+ {
+ return m_args.data ();
+ }
+
+ /* Return a constant reference to the underlying vector. */
+ const decltype (m_args) &get () const
+ {
+ return m_args;
+ }
+
+ /* Return true when m_args is empty. */
+ bool empty () const
+ {
+ return m_args.empty ();
+ }
+};
+} /* namespac gdb */
+
+#endif /* GDBSUPPORT_GDB_ARGV_VEC_H */