public inbox for
help / color / mirror / Atom feed
* [binutils-gdb] gdb: use gdb::unique_xmalloc_ptr<char> for docs in cmdpy_init
@ 2022-05-28 10:07 Andrew Burgess
  0 siblings, 0 replies; only message in thread
From: Andrew Burgess @ 2022-05-28 10:07 UTC (permalink / raw)
  To: gdb-cvs;h=0e77ff2c86a163fe11135633837c8f19aee31ca0

commit 0e77ff2c86a163fe11135633837c8f19aee31ca0
Author: Andrew Burgess <>
Date:   Sat May 14 10:55:59 2022 +0100

    gdb: use gdb::unique_xmalloc_ptr<char> for docs in cmdpy_init
    Make use of gdb::unique_xmalloc_ptr<char> to hold the documentation
    string in cmdpy_init (when creating a custom GDB command in Python).
    I think this is all pretty straight forward, the only slight weirdness
    is the removal of the call to free toward the end of this function.
    Prior to this commit, if an exception was thrown after the GDB command
    was created then we would (I think) end up freeing the documentation
    string even though the command would remain registered with GDB, which
    would surely lead to undefined behaviour.
    After this commit we release the doc string at the point that we hand
    it over to the command creation routines.  If we throw _after_ the
    command has been created within GDB then the doc string will be left
    live.  If we throw during the command creation itself (either from
    add_prefix_cmd or add_cmd) then it is up to those functions to free
    the doc string (I suspect we don't, but I think in general the
    commands are pretty bad at cleaning up after themselves, so I don't
    think this is a huge problem).

 gdb/python/py-cmd.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index c0a98544619..bc48c2ea9f9 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -430,7 +430,6 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
   const char *name;
   int cmdtype;
   int completetype = -1;
-  char *docstring = NULL;
   struct cmd_list_element **cmd_list;
   static const char *keywords[] = { "name", "command_class", "completer_class",
 				    "prefix", NULL };
@@ -484,19 +483,20 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
       is_prefix = cmp > 0;
+  gdb::unique_xmalloc_ptr<char> docstring = nullptr;
   if (PyObject_HasAttr (self, gdbpy_doc_cst))
       gdbpy_ref<> ds_obj (PyObject_GetAttr (self, gdbpy_doc_cst));
       if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
-	  docstring = python_string_to_host_string (ds_obj.get ()).release ();
-	  if (docstring == NULL)
+	  docstring = python_string_to_host_string (ds_obj.get ());
+	  if (docstring == nullptr)
 	    return -1;
-  if (! docstring)
-    docstring = xstrdup (_("This command is not documented."));
+  if (docstring == nullptr)
+    docstring = make_unique_xstrdup (_("This command is not documented."));
   gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self);
@@ -513,12 +513,12 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
 	  allow_unknown = PyObject_HasAttr (self, invoke_cst);
 	  cmd = add_prefix_cmd (cmd_name.get (),
 				(enum command_class) cmdtype,
-				NULL, docstring, &obj->sub_list,
+				NULL, docstring.release (), &obj->sub_list,
 				allow_unknown, cmd_list);
 	cmd = add_cmd (cmd_name.get (), (enum command_class) cmdtype,
-		       docstring, cmd_list);
+		       docstring.release (), cmd_list);
       /* If successful, the above takes ownership of the name, since we set
          name_allocated, so release it.  */
@@ -540,7 +540,6 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
   catch (const gdb_exception &except)
-      xfree (docstring);
       gdbpy_convert_exception (except);
       return -1;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-28 10:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-28 10:07 [binutils-gdb] gdb: use gdb::unique_xmalloc_ptr<char> for docs in cmdpy_init Andrew Burgess

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).