Patchwork [RFA,v3,19/23] Avoid some manual memory management in Python

login
register
mail settings
Submitter Tom Tromey
Date Aug. 2, 2017, 3:02 p.m.
Message ID <20170802150227.24460-20-tom@tromey.com>
Download mbox | patch
Permalink /patch/21850/
State New
Headers show

Comments

Tom Tromey - Aug. 2, 2017, 3:02 p.m.
This changes a few places in the Python code to avoid manual memory
management, in favor of letting std::string do the work.

ChangeLog
2017-08-02  Tom Tromey  <tom@tromey.com>

	* python/python.c (compute_python_string): Return std::string.
	(gdbpy_eval_from_control_command): Update.
	(do_start_initialization): Use std::string.
	* python/py-varobj.c (py_varobj_iter_next): Use string_printf, not
	xstrprintf.
	* python/py-breakpoint.c (local_setattro): Use string_printf, not
	xstrprintf.
---
 gdb/ChangeLog              | 10 ++++++++++
 gdb/python/py-breakpoint.c | 15 ++++++---------
 gdb/python/py-varobj.c     |  9 ++++-----
 gdb/python/python.c        | 37 +++++++++----------------------------
 4 files changed, 29 insertions(+), 42 deletions(-)

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 892bf52..9c4c05a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@ 
 2017-08-02  Tom Tromey  <tom@tromey.com>
 
+	* python/python.c (compute_python_string): Return std::string.
+	(gdbpy_eval_from_control_command): Update.
+	(do_start_initialization): Use std::string.
+	* python/py-varobj.c (py_varobj_iter_next): Use string_printf, not
+	xstrprintf.
+	* python/py-breakpoint.c (local_setattro): Use string_printf, not
+	xstrprintf.
+
+2017-08-02  Tom Tromey  <tom@tromey.com>
+
 	* top.h (do_restore_instream_cleanup): Remove.
 	* top.c (do_restore_instream_cleanup): Remove.
 	(read_command_file): Use scoped_restore.
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 64de803..6156eb6 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -1026,15 +1026,12 @@  local_setattro (PyObject *self, PyObject *name, PyObject *v)
 	extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
       if (extlang != NULL)
 	{
-	  char *error_text;
-
-	  error_text
-	    = xstrprintf (_("Only one stop condition allowed.  There is"
-			    " currently a %s stop condition defined for"
-			    " this breakpoint."),
-			  ext_lang_capitalized_name (extlang));
-	  PyErr_SetString (PyExc_RuntimeError, error_text);
-	  xfree (error_text);
+	  std::string error_text
+	    = string_printf (_("Only one stop condition allowed.  There is"
+			       " currently a %s stop condition defined for"
+			       " this breakpoint."),
+			     ext_lang_capitalized_name (extlang));
+	  PyErr_SetString (PyExc_RuntimeError, error_text.c_str ());
 	  return -1;
 	}
     }
diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index e858556..5f6ab64 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -71,7 +71,6 @@  py_varobj_iter_next (struct varobj_iter *self)
       if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
 	{
 	  PyObject *type, *value, *trace;
-	  char *name_str;
 
 	  PyErr_Fetch (&type, &value, &trace);
 	  gdb::unique_xmalloc_ptr<char>
@@ -85,10 +84,10 @@  py_varobj_iter_next (struct varobj_iter *self)
 	      return NULL;
 	    }
 
-	  name_str = xstrprintf ("<error at %d>",
-				 self->next_raw_index++);
-	  item.reset (Py_BuildValue ("(ss)", name_str, value_str.get ()));
-	  xfree (name_str);
+	  std::string name_str = string_printf ("<error at %d>",
+						self->next_raw_index++);
+	  item.reset (Py_BuildValue ("(ss)", name_str.c_str (),
+				     value_str.get ()));
 	  if (item == NULL)
 	    {
 	      gdbpy_print_stack ();
diff --git a/gdb/python/python.c b/gdb/python/python.c
index be92f36..67f134d 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -365,32 +365,19 @@  python_run_simple_file (FILE *file, const char *filename)
 }
 
 /* Given a command_line, return a command string suitable for passing
-   to Python.  Lines in the string are separated by newlines.  The
-   return value is allocated using xmalloc and the caller is
-   responsible for freeing it.  */
+   to Python.  Lines in the string are separated by newlines.  */
 
-static char *
+static std::string
 compute_python_string (struct command_line *l)
 {
   struct command_line *iter;
-  char *script = NULL;
-  int size = 0;
-  int here;
+  std::string script;
 
   for (iter = l; iter; iter = iter->next)
-    size += strlen (iter->line) + 1;
-
-  script = (char *) xmalloc (size + 1);
-  here = 0;
-  for (iter = l; iter; iter = iter->next)
     {
-      int len = strlen (iter->line);
-
-      strcpy (&script[here], iter->line);
-      here += len;
-      script[here++] = '\n';
+      script += iter->line;
+      script += '\n';
     }
-  script[here] = '\0';
   return script;
 }
 
@@ -402,16 +389,14 @@  gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
 				 struct command_line *cmd)
 {
   int ret;
-  char *script;
 
   if (cmd->body_count != 1)
     error (_("Invalid \"python\" block structure."));
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
-  script = compute_python_string (cmd->body_list[0]);
-  ret = PyRun_SimpleString (script);
-  xfree (script);
+  std::string script = compute_python_string (cmd->body_list[0]);
+  ret = PyRun_SimpleString (script.c_str ());
   if (ret)
     error (_("Error while executing Python code."));
 }
@@ -1532,7 +1517,6 @@  do_start_initialization ()
 #ifdef IS_PY3K
   int i;
   size_t progsize, count;
-  char *oldloc;
   wchar_t *progname_copy;
 #endif
 
@@ -1546,25 +1530,22 @@  do_start_initialization ()
   progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin",
 		     SLASH_STRING, "python", (char *) NULL);
 #ifdef IS_PY3K
-  oldloc = xstrdup (setlocale (LC_ALL, NULL));
+  std::string oldloc = setlocale (LC_ALL, NULL);
   setlocale (LC_ALL, "");
   progsize = strlen (progname);
   progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
   if (!progname_copy)
     {
-      xfree (oldloc);
       fprintf (stderr, "out of memory\n");
       return false;
     }
   count = mbstowcs (progname_copy, progname, progsize + 1);
   if (count == (size_t) -1)
     {
-      xfree (oldloc);
       fprintf (stderr, "Could not convert python path to string\n");
       return false;
     }
-  setlocale (LC_ALL, oldloc);
-  xfree (oldloc);
+  setlocale (LC_ALL, oldloc.c_str ());
 
   /* Note that Py_SetProgramName expects the string it is passed to
      remain alive for the duration of the program's execution, so