diff mbox

[RFA] Use unique_xmalloc_ptr in Python code

Message ID 1478292124-26362-1-git-send-email-tom@tromey.com
State New
Headers show

Commit Message

Tom Tromey Nov. 4, 2016, 8:42 p.m. UTC
This changes some utility functions in the Python code to return
unique_xmalloc_ptr, and then fixes up the callers.

I chose unique_xmalloc_ptr rather than std::string because at a few
call points the xmalloc'd string is released and ownership transferred
elsewhere.

This patch found a few existing memory leaks.  For example,
py-unwind.c called gdbpy_obj_to_string but never freed the result.

Built and regression tested on the buildbot.

2016-11-04  Tom Tromey  <tom@tromey.com>

	* varobj.h (varobj_get_display_hint): Change return type.
	* varobj.c (varobj_get_display_hint): Return unique_xmalloc_ptr.
	(varobj_value_get_print_value): Update.
	* python/python.c (gdbpy_before_prompt_hook, gdbpy_print_stack)
	(gdbpy_apply_type_printers): Update.
	* python/python-internal.h (unicode_to_target_string)
	(python_string_to_target_string, python_string_to_host_string)
	(gdbpy_obj_to_string, gdbpy_exception_to_string)
	(gdbpy_get_display_hint): Change return types.
	* python/py-varobj.c (py_varobj_iter_next): Update.
	* python/py-value.c (valpy_getitem, convert_value_from_python):
	Update.
	* python/py-utils.c (unicode_to_encoded_string)
	(unicode_to_target_string, python_string_to_target_string)
	(python_string_to_host_string, gdbpy_obj_to_string)
	(gdbpy_exception_to_string): Return unique_xmalloc_ptr.
	* python/py-unwind.c (pyuw_parse_register_id): Update.
	* python/py-type.c (typy_getitem): Update.
	* python/py-prettyprint.c (gdbpy_get_display_hint)
	(print_stack_unless_memory_error, print_children)
	(gdbpy_apply_val_pretty_printer): Update.
	* python/py-param.c (set_parameter_value): Update.
	(get_doc_string, call_doc_function): Return unique_xmalloc_ptr.
	(get_set_value, get_show_value, compute_enum_values, parmpy_init):
	Update.
	* python/py-infthread.c (thpy_set_name): Update.
	* python/py-function.c (fnpy_call, fnpy_init): Update.
	* python/py-framefilter.c (extract_sym): Change "name" to
	unique_xmalloc_ptr.
	(enumerate_args, enumerate_locals): Update.
	(py_print_frame): Use unique_xmalloc_ptr.
	* python/py-frame.c (frapy_read_var): Update.  Remove cleanup.
	* python/py-cmd.c (cmdpy_function, cmdpy_completer, cmdpy_init):
	Update.
	* python/py-breakpoint.c (bppy_set_condition): Use
	unique_xmalloc_ptr.
	(bppy_init): Likewise.  Remove cleanup.
	(local_setattro): Update.
	* mi/mi-cmd-var.c (print_varobj, mi_cmd_var_list_children)
	(varobj_update_one): Update.
---
 gdb/ChangeLog                | 43 +++++++++++++++++++++++++++++++
 gdb/mi/mi-cmd-var.c          | 25 ++++++------------
 gdb/python/py-breakpoint.c   | 30 +++++++++++-----------
 gdb/python/py-cmd.c          | 17 ++++++-------
 gdb/python/py-frame.c        | 15 +++--------
 gdb/python/py-framefilter.c  | 52 +++++++++++++-------------------------
 gdb/python/py-function.c     | 15 ++++++-----
 gdb/python/py-infthread.c    |  8 +++---
 gdb/python/py-param.c        | 46 +++++++++++++++------------------
 gdb/python/py-prettyprint.c  | 26 ++++++++-----------
 gdb/python/py-type.c         |  5 ++--
 gdb/python/py-unwind.c       |  6 ++---
 gdb/python/py-utils.c        | 60 +++++++++++++++++++-------------------------
 gdb/python/py-value.c        | 19 +++++---------
 gdb/python/py-varobj.c       |  8 +++---
 gdb/python/python-internal.h | 13 +++++-----
 gdb/python/python.c          | 24 +++++++++---------
 gdb/varobj.c                 | 20 +++++++--------
 gdb/varobj.h                 |  3 ++-
 19 files changed, 209 insertions(+), 226 deletions(-)

Comments

Pedro Alves Nov. 9, 2016, 11:20 p.m. UTC | #1
On 11/04/2016 08:42 PM, Tom Tromey wrote:
> This changes some utility functions in the Python code to return
> unique_xmalloc_ptr, and then fixes up the callers.
> 
> I chose unique_xmalloc_ptr rather than std::string because at a few
> call points the xmalloc'd string is released and ownership transferred
> elsewhere.

IMO, for simplicity sake, we should default to use std::string, unless
we're ending up storing the result in some long lived objects where
memory really is a concern (because of many instances), and a final
string dup/copy to destination wouldn't be too heavy too.  I doubt
that's the case here, but it's not easy to see without trying.
Did you try a std::string approach first?

In any case, this is strictly an improvement, so OK with me.  Please
push.  Let's get this out of the way of your py-ref series.
We can convert to std::string at some other point, if desirable.

Thanks,
Pedro Alves
Tom Tromey Nov. 9, 2016, 11:39 p.m. UTC | #2
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> IMO, for simplicity sake, we should default to use std::string, unless
Pedro> we're ending up storing the result in some long lived objects where
Pedro> memory really is a concern (because of many instances), and a final
Pedro> string dup/copy to destination wouldn't be too heavy too.  I doubt
Pedro> that's the case here, but it's not easy to see without trying.
Pedro> Did you try a std::string approach first?

Nope, I had just started with unique_xmalloc_ptr, and then noticed a few
spots -- basically anywhere in the patch calling .release() -- where the
ownership is passed on.

I didn't really consider that copying the string would be ok.  I agree
it is, I think I was just being conservative in preserving existing
behavior.

Pedro> In any case, this is strictly an improvement, so OK with me.  Please
Pedro> push.  Let's get this out of the way of your py-ref series.
Pedro> We can convert to std::string at some other point, if desirable.

Will do.  Thanks.

Tom
diff mbox

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8e173a7..ac5cdd2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,46 @@ 
+2016-11-04  Tom Tromey  <tom@tromey.com>
+
+	* varobj.h (varobj_get_display_hint): Change return type.
+	* varobj.c (varobj_get_display_hint): Return unique_xmalloc_ptr.
+	(varobj_value_get_print_value): Update.
+	* python/python.c (gdbpy_before_prompt_hook, gdbpy_print_stack)
+	(gdbpy_apply_type_printers): Update.
+	* python/python-internal.h (unicode_to_target_string)
+	(python_string_to_target_string, python_string_to_host_string)
+	(gdbpy_obj_to_string, gdbpy_exception_to_string)
+	(gdbpy_get_display_hint): Change return types.
+	* python/py-varobj.c (py_varobj_iter_next): Update.
+	* python/py-value.c (valpy_getitem, convert_value_from_python):
+	Update.
+	* python/py-utils.c (unicode_to_encoded_string)
+	(unicode_to_target_string, python_string_to_target_string)
+	(python_string_to_host_string, gdbpy_obj_to_string)
+	(gdbpy_exception_to_string): Return unique_xmalloc_ptr.
+	* python/py-unwind.c (pyuw_parse_register_id): Update.
+	* python/py-type.c (typy_getitem): Update.
+	* python/py-prettyprint.c (gdbpy_get_display_hint)
+	(print_stack_unless_memory_error, print_children)
+	(gdbpy_apply_val_pretty_printer): Update.
+	* python/py-param.c (set_parameter_value): Update.
+	(get_doc_string, call_doc_function): Return unique_xmalloc_ptr.
+	(get_set_value, get_show_value, compute_enum_values, parmpy_init):
+	Update.
+	* python/py-infthread.c (thpy_set_name): Update.
+	* python/py-function.c (fnpy_call, fnpy_init): Update.
+	* python/py-framefilter.c (extract_sym): Change "name" to
+	unique_xmalloc_ptr.
+	(enumerate_args, enumerate_locals): Update.
+	(py_print_frame): Use unique_xmalloc_ptr.
+	* python/py-frame.c (frapy_read_var): Update.  Remove cleanup.
+	* python/py-cmd.c (cmdpy_function, cmdpy_completer, cmdpy_init):
+	Update.
+	* python/py-breakpoint.c (bppy_set_condition): Use
+	unique_xmalloc_ptr.
+	(bppy_init): Likewise.  Remove cleanup.
+	(local_setattro): Update.
+	* mi/mi-cmd-var.c (print_varobj, mi_cmd_var_list_children)
+	(varobj_update_one): Update.
+
 2016-10-29  Manish Goregaokar  <manish@mozilla.com>
 
     * rust-exp.y: Parse `sizeof(exp)` as `UNOP_SIZEOF`
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 16d51f9..05cf4bb 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -51,7 +51,6 @@  print_varobj (struct varobj *var, enum print_values print_values,
   struct ui_out *uiout = current_uiout;
   char *type;
   int thread_id;
-  char *display_hint;
 
   ui_out_field_string (uiout, "name", varobj_get_objname (var));
   if (print_expression)
@@ -85,12 +84,9 @@  print_varobj (struct varobj *var, enum print_values print_values,
   if (varobj_get_frozen (var))
     ui_out_field_int (uiout, "frozen", 1);
 
-  display_hint = varobj_get_display_hint (var);
+  gdb::unique_xmalloc_ptr<char> display_hint = varobj_get_display_hint (var);
   if (display_hint)
-    {
-      ui_out_field_string (uiout, "displayhint", display_hint);
-      xfree (display_hint);
-    }
+    ui_out_field_string (uiout, "displayhint", display_hint.get ());
 
   if (varobj_is_dynamic_p (var))
     ui_out_field_int (uiout, "dynamic", 1);
@@ -386,7 +382,6 @@  mi_cmd_var_list_children (char *command, char **argv, int argc)
   enum print_values print_values;
   int ix;
   int from, to;
-  char *display_hint;
 
   if (argc < 1 || argc > 4)
     error (_("-var-list-children: Usage: "
@@ -416,12 +411,9 @@  mi_cmd_var_list_children (char *command, char **argv, int argc)
   else
     print_values = PRINT_NO_VALUES;
 
-  display_hint = varobj_get_display_hint (var);
+  gdb::unique_xmalloc_ptr<char> display_hint = varobj_get_display_hint (var);
   if (display_hint)
-    {
-      ui_out_field_string (uiout, "displayhint", display_hint);
-      xfree (display_hint);
-    }
+    ui_out_field_string (uiout, "displayhint", display_hint.get ());
 
   if (from < to)
     {
@@ -739,7 +731,6 @@  varobj_update_one (struct varobj *var, enum print_values print_values,
   
   for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
     {
-      char *display_hint;
       int from, to;
       struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
 
@@ -787,12 +778,10 @@  varobj_update_one (struct varobj *var, enum print_values print_values,
 	ui_out_field_int (uiout, "new_num_children", 
 			  varobj_get_num_children (r->varobj));
 
-      display_hint = varobj_get_display_hint (r->varobj);
+      gdb::unique_xmalloc_ptr<char> display_hint
+	= varobj_get_display_hint (r->varobj);
       if (display_hint)
-	{
-	  ui_out_field_string (uiout, "displayhint", display_hint);
-	  xfree (display_hint);
-	}
+	ui_out_field_string (uiout, "displayhint", display_hint.get ());
 
       if (varobj_is_dynamic_p (r->varobj))
 	ui_out_field_int (uiout, "dynamic", 1);
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 80f5d1f..ef6533f 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -440,7 +440,8 @@  bppy_get_condition (PyObject *self, void *closure)
 static int
 bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
 {
-  char *exp;
+  gdb::unique_xmalloc_ptr<char> exp_holder;
+  const char *exp = NULL;
   gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
   struct gdb_exception except = exception_none;
 
@@ -456,9 +457,10 @@  bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
     exp = "";
   else
     {
-      exp = python_string_to_host_string (newvalue);
-      if (exp == NULL)
+      exp_holder = python_string_to_host_string (newvalue);
+      if (exp_holder == NULL)
 	return -1;
+      exp = exp_holder.get ();
     }
 
   TRY
@@ -471,9 +473,6 @@  bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
     }
   END_CATCH
 
-  if (newvalue != Py_None)
-    xfree (exp);
-
   GDB_PY_SET_HANDLE_EXCEPTION (except);
 
   return 0;
@@ -682,18 +681,20 @@  bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 
   TRY
     {
-      char *copy = xstrdup (skip_spaces_const (spec));
-      struct cleanup *cleanup = make_cleanup (xfree, copy);
+      gdb::unique_xmalloc_ptr<char>
+	copy_holder (xstrdup (skip_spaces_const (spec)));
+      char *copy = copy_holder.get ();
 
       switch (type)
 	{
 	case bp_breakpoint:
 	  {
 	    struct event_location *location;
+	    struct cleanup *cleanup;
 
 	    location
 	      = string_to_event_location_basic (&copy, current_language);
-	    make_cleanup_delete_event_location (location);
+	    cleanup = make_cleanup_delete_event_location (location);
 	    create_breakpoint (python_gdbarch,
 			       location, NULL, -1, NULL,
 			       0,
@@ -702,6 +703,8 @@  bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 			       AUTO_BOOLEAN_TRUE,
 			       &bkpt_breakpoint_ops,
 			       0, 1, internal_bp, 0);
+
+	    do_cleanups (cleanup);
 	    break;
 	  }
         case bp_watchpoint:
@@ -719,8 +722,6 @@  bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 	default:
 	  error(_("Do not understand breakpoint type to set."));
 	}
-
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1045,7 +1046,7 @@  static int
 local_setattro (PyObject *self, PyObject *name, PyObject *v)
 {
   gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
-  char *attr = python_string_to_host_string (name);
+  gdb::unique_xmalloc_ptr<char> attr (python_string_to_host_string (name));
 
   if (attr == NULL)
     return -1;
@@ -1053,7 +1054,7 @@  local_setattro (PyObject *self, PyObject *name, PyObject *v)
   /* If the attribute trying to be set is the "stop" method,
      but we already have a condition set in the CLI or other extension
      language, disallow this operation.  */
-  if (strcmp (attr, stop_func) == 0)
+  if (strcmp (attr.get (), stop_func) == 0)
     {
       const struct extension_language_defn *extlang = NULL;
 
@@ -1065,7 +1066,6 @@  local_setattro (PyObject *self, PyObject *name, PyObject *v)
 	{
 	  char *error_text;
 
-	  xfree (attr);
 	  error_text
 	    = xstrprintf (_("Only one stop condition allowed.  There is"
 			    " currently a %s stop condition defined for"
@@ -1077,8 +1077,6 @@  local_setattro (PyObject *self, PyObject *name, PyObject *v)
 	}
     }
 
-  xfree (attr);
-
   return PyObject_GenericSetAttr ((PyObject *)self, name, v);
 }
 
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index af6c5cf..8333789 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -156,7 +156,6 @@  cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
   if (! result)
     {
       PyObject *ptype, *pvalue, *ptraceback;
-      char *msg;
 
       PyErr_Fetch (&ptype, &pvalue, &ptraceback);
 
@@ -164,8 +163,8 @@  cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
 	 When fetching the error message we need to make our own copy,
 	 we no longer own ptype, pvalue after the call to PyErr_Restore.  */
 
-      msg = gdbpy_exception_to_string (ptype, pvalue);
-      make_cleanup (xfree, msg);
+      gdb::unique_xmalloc_ptr<char>
+	msg (gdbpy_exception_to_string (ptype, pvalue));
 
       if (msg == NULL)
 	{
@@ -190,7 +189,7 @@  cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
 	  PyErr_Restore (ptype, pvalue, ptraceback);
 	  gdbpy_print_stack ();
 	  if (msg != NULL && *msg != '\0')
-	    error (_("Error occurred in Python command: %s"), msg);
+	    error (_("Error occurred in Python command: %s"), msg.get ());
 	  else
 	    error (_("Error occurred in Python command."));
 	}
@@ -199,7 +198,7 @@  cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
 	  Py_XDECREF (ptype);
 	  Py_XDECREF (pvalue);
 	  Py_XDECREF (ptraceback);
-	  error ("%s", msg);
+	  error ("%s", msg.get ());
 	}
     }
 
@@ -374,7 +373,6 @@  cmdpy_completer (struct cmd_list_element *command,
 
       while ((elt = PyIter_Next (iter)) != NULL)
 	{
-	  char *item;
 
 	  if (! gdbpy_is_string (elt))
 	    {
@@ -382,7 +380,8 @@  cmdpy_completer (struct cmd_list_element *command,
 	      Py_DECREF (elt);
 	      continue;
 	    }
-	  item = python_string_to_host_string (elt);
+	  gdb::unique_xmalloc_ptr<char>
+	    item (python_string_to_host_string (elt));
 	  Py_DECREF (elt);
 	  if (item == NULL)
 	    {
@@ -390,7 +389,7 @@  cmdpy_completer (struct cmd_list_element *command,
 	      PyErr_Clear ();
 	      continue;
 	    }
-	  VEC_safe_push (char_ptr, result, item);
+	  VEC_safe_push (char_ptr, result, item.release ());
 	}
 
       Py_DECREF (iter);
@@ -604,7 +603,7 @@  cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
 
       if (ds_obj && gdbpy_is_string (ds_obj))
 	{
-	  docstring = python_string_to_host_string (ds_obj);
+	  docstring = python_string_to_host_string (ds_obj).release ();
 	  if (docstring == NULL)
 	    {
 	      xfree (cmd_name);
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 6bdac08..7827cde 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -518,13 +518,11 @@  frapy_read_var (PyObject *self, PyObject *args)
     var = symbol_object_to_symbol (sym_obj);
   else if (gdbpy_is_string (sym_obj))
     {
-      char *var_name;
-      struct cleanup *cleanup;
+      gdb::unique_xmalloc_ptr<char>
+	var_name (python_string_to_target_string (sym_obj));
 
-      var_name = python_string_to_target_string (sym_obj);
       if (!var_name)
 	return NULL;
-      cleanup = make_cleanup (xfree, var_name);
 
       if (block_obj)
 	{
@@ -533,7 +531,6 @@  frapy_read_var (PyObject *self, PyObject *args)
 	    {
 	      PyErr_SetString (PyExc_RuntimeError,
 			       _("Second argument must be block."));
-	      do_cleanups (cleanup);
 	      return NULL;
 	    }
 	}
@@ -545,13 +542,12 @@  frapy_read_var (PyObject *self, PyObject *args)
 
 	  if (!block)
 	    block = get_frame_block (frame, NULL);
-	  lookup_sym = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
+	  lookup_sym = lookup_symbol (var_name.get (), block, VAR_DOMAIN, NULL);
 	  var = lookup_sym.symbol;
 	  block = lookup_sym.block;
 	}
       CATCH (except, RETURN_MASK_ALL)
 	{
-	  do_cleanups (cleanup);
 	  gdbpy_convert_exception (except);
 	  return NULL;
 	}
@@ -560,13 +556,10 @@  frapy_read_var (PyObject *self, PyObject *args)
       if (!var)
 	{
 	  PyErr_Format (PyExc_ValueError,
-			_("Variable '%s' not found."), var_name);
-	  do_cleanups (cleanup);
+			_("Variable '%s' not found."), var_name.get ());
 
 	  return NULL;
 	}
-
-      do_cleanups (cleanup);
     }
   else
     {
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 6692ac5..6722032 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -52,8 +52,9 @@  enum mi_print_types
    appropriate Python exception set, and EXT_LANG_BT_OK on success.  */
 
 static enum ext_lang_bt_status
-extract_sym (PyObject *obj, char **name, struct symbol **sym,
-	     struct block **sym_block, const struct language_defn **language)
+extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr<char> *name,
+	     struct symbol **sym, struct block **sym_block,
+	     const struct language_defn **language)
 {
   PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
 
@@ -101,7 +102,7 @@  extract_sym (PyObject *obj, char **name, struct symbol **sym,
 
       /* Duplicate the symbol name, so the caller has consistency
 	 in garbage collection.  */
-      *name = xstrdup (SYMBOL_PRINT_NAME (*sym));
+      name->reset (xstrdup (SYMBOL_PRINT_NAME (*sym)));
 
       /* If a symbol is specified attempt to determine the language
 	 from the symbol.  If mode is not "auto", then the language
@@ -538,7 +539,7 @@  enumerate_args (PyObject *iter,
   while (item)
     {
       const struct language_defn *language;
-      char *sym_name;
+      gdb::unique_xmalloc_ptr<char> sym_name;
       struct symbol *sym;
       struct block *sym_block;
       struct value *val;
@@ -554,7 +555,6 @@  enumerate_args (PyObject *iter,
       success = extract_value (item, &val);
       if (success == EXT_LANG_BT_ERROR)
 	{
-	  xfree (sym_name);
 	  Py_DECREF (item);
 	  goto error;
 	}
@@ -564,10 +564,7 @@  enumerate_args (PyObject *iter,
 
       if (sym && ui_out_is_mi_like_p (out)
 	  && ! mi_should_print (sym, MI_PRINT_ARGS))
-	{
-	  xfree (sym_name);
-	  continue;
-	}
+	continue;
 
       /* If the object did not provide a value, read it using
 	 read_frame_args and account for entry values, if any.  */
@@ -581,7 +578,6 @@  enumerate_args (PyObject *iter,
 	    {
 	      PyErr_SetString (PyExc_RuntimeError,
 			       _("No symbol or value provided."));
-	      xfree (sym_name);
 	      goto error;
 	    }
 
@@ -591,7 +587,6 @@  enumerate_args (PyObject *iter,
 	    }
 	  CATCH (except, RETURN_MASK_ALL)
 	    {
-	      xfree (sym_name);
 	      gdbpy_convert_exception (except);
 	      goto error;
 	    }
@@ -611,7 +606,6 @@  enumerate_args (PyObject *iter,
 		{
 		  xfree (arg.error);
 		  xfree (entryarg.error);
-		  xfree (sym_name);
 		  goto error;
 		}
 	    }
@@ -629,7 +623,6 @@  enumerate_args (PyObject *iter,
 		    {
 		      xfree (arg.error);
 		      xfree (entryarg.error);
-		      xfree (sym_name);
 		      gdbpy_convert_exception (except);
 		      goto error;
 		    }
@@ -642,7 +635,6 @@  enumerate_args (PyObject *iter,
 		{
 		      xfree (arg.error);
 		      xfree (entryarg.error);
-		      xfree (sym_name);
 		      goto error;
 		}
 	    }
@@ -655,18 +647,13 @@  enumerate_args (PyObject *iter,
 	  /* If the object has provided a value, we just print that.  */
 	  if (val != NULL)
 	    {
-	      if (py_print_single_arg (out, sym_name, NULL, val, &opts,
+	      if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts,
 				       args_type, print_args_field,
 				       language) == EXT_LANG_BT_ERROR)
-		{
-		  xfree (sym_name);
-		  goto error;
-		}
+		goto error;
 	    }
 	}
 
-      xfree (sym_name);
-
       /* Collect the next item from the iterator.  If
 	 this is the last item, do not print the
 	 comma.  */
@@ -736,7 +723,7 @@  enumerate_locals (PyObject *iter,
   while ((item = PyIter_Next (iter)))
     {
       const struct language_defn *language;
-      char *sym_name;
+      gdb::unique_xmalloc_ptr<char> sym_name;
       struct value *val;
       enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
       struct symbol *sym;
@@ -753,8 +740,6 @@  enumerate_locals (PyObject *iter,
 	  goto error;
 	}
 
-      make_cleanup (xfree, sym_name);
-
       success = extract_value (item, &val);
       if (success == EXT_LANG_BT_ERROR)
 	{
@@ -801,7 +786,7 @@  enumerate_locals (PyObject *iter,
 	      ui_out_spaces (out, local_indent);
 	    }
 
-	  ui_out_field_string (out, "name", sym_name);
+	  ui_out_field_string (out, "name", sym_name.get ());
 
 	  if (! ui_out_is_mi_like_p (out))
 	    ui_out_text (out, " = ");
@@ -1033,6 +1018,7 @@  py_print_frame (PyObject *filter, int flags,
   struct value_print_options opts;
   PyObject *py_inf_frame;
   int print_level, print_frame_info, print_args, print_locals;
+  gdb::unique_xmalloc_ptr<char> function_to_free;
 
   /* Extract print settings from FLAGS.  */
   print_level = (flags & PRINT_LEVEL) ? 1 : 0;
@@ -1199,17 +1185,15 @@  py_print_frame (PyObject *filter, int flags,
 
 	  if (gdbpy_is_string (py_func))
 	    {
-	      char *function_to_free;
-
-	      function = function_to_free =
-		python_string_to_host_string (py_func);
+	      function_to_free = python_string_to_host_string (py_func);
 
-	      if (function == NULL)
+	      if (function_to_free == NULL)
 		{
 		  do_cleanups (cleanup_stack);
 		  return EXT_LANG_BT_ERROR;
 		}
-	      make_cleanup (xfree, function_to_free);
+
+	      function = function_to_free.get ();
 	    }
 	  else if (PyLong_Check (py_func))
 	    {
@@ -1296,7 +1280,8 @@  py_print_frame (PyObject *filter, int flags,
 
 	  if (py_fn != Py_None)
 	    {
-	      char *filename = python_string_to_host_string (py_fn);
+	      gdb::unique_xmalloc_ptr<char>
+		filename (python_string_to_host_string (py_fn));
 
 	      if (filename == NULL)
 		{
@@ -1304,13 +1289,12 @@  py_print_frame (PyObject *filter, int flags,
 		  return EXT_LANG_BT_ERROR;
 		}
 
-	      make_cleanup (xfree, filename);
 	      TRY
 		{
 		  ui_out_wrap_hint (out, "   ");
 		  ui_out_text (out, " at ");
 		  annotate_frame_source_file ();
-		  ui_out_field_string (out, "file", filename);
+		  ui_out_field_string (out, "file", filename.get ());
 		  annotate_frame_source_file_end ();
 		}
 	      CATCH (except, RETURN_MASK_ERROR)
diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c
index d42dbde..800605a 100644
--- a/gdb/python/py-function.c
+++ b/gdb/python/py-function.c
@@ -94,7 +94,6 @@  fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
   if (!result)
     {
       PyObject *ptype, *pvalue, *ptraceback;
-      char *msg;
 
       PyErr_Fetch (&ptype, &pvalue, &ptraceback);
 
@@ -102,8 +101,8 @@  fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
 	 When fetching the error message we need to make our own copy,
 	 we no longer own ptype, pvalue after the call to PyErr_Restore.  */
 
-      msg = gdbpy_exception_to_string (ptype, pvalue);
-      make_cleanup (xfree, msg);
+      gdb::unique_xmalloc_ptr<char>
+	msg (gdbpy_exception_to_string (ptype, pvalue));
 
       if (msg == NULL)
 	{
@@ -131,7 +130,7 @@  fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
 	  gdbpy_print_stack ();
 	  if (msg != NULL && *msg != '\0')
 	    error (_("Error occurred in Python convenience function: %s"),
-		   msg);
+		   msg.get ());
 	  else
 	    error (_("Error occurred in Python convenience function."));
 	}
@@ -140,7 +139,7 @@  fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
 	  Py_XDECREF (ptype);
 	  Py_XDECREF (pvalue);
 	  Py_XDECREF (ptraceback);
-	  error ("%s", msg);
+	  error ("%s", msg.get ());
 	}
     }
 
@@ -165,7 +164,7 @@  static int
 fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
 {
   const char *name;
-  char *docstring = NULL;
+  gdb::unique_xmalloc_ptr<char> docstring;
 
   if (! PyArg_ParseTuple (args, "s", &name))
     return -1;
@@ -191,9 +190,9 @@  fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
 	}
     }
   if (! docstring)
-    docstring = xstrdup (_("This function is not documented."));
+    docstring.reset (xstrdup (_("This function is not documented.")));
 
-  add_internal_function (name, docstring, fnpy_call, self);
+  add_internal_function (name, docstring.release (), fnpy_call, self);
   return 0;
 }
 
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 697298d..3cc359c 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -80,7 +80,7 @@  static int
 thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore)
 {
   thread_object *thread_obj = (thread_object *) self;
-  char *name;
+  gdb::unique_xmalloc_ptr<char> name;
 
   if (! thread_obj->thread)
     {
@@ -95,7 +95,9 @@  thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore)
       return -1;
     }
   else if (newvalue == Py_None)
-    name = NULL;
+    {
+      /* Nothing.  */
+    }
   else if (! gdbpy_is_string (newvalue))
     {
       PyErr_SetString (PyExc_TypeError,
@@ -110,7 +112,7 @@  thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore)
     }
 
   xfree (thread_obj->thread->name);
-  thread_obj->thread->name = name;
+  thread_obj->thread->name = name.release ();
 
   return 0;
 }
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index 3604f9f..0d19c97 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -148,21 +148,19 @@  set_parameter_value (parmpy_object *self, PyObject *value)
 	}
       else
 	{
-	  char *string;
-
-	  string = python_string_to_host_string (value);
+	  gdb::unique_xmalloc_ptr<char>
+	    string (python_string_to_host_string (value));
 	  if (string == NULL)
 	    return -1;
 
 	  xfree (self->value.stringval);
-	  self->value.stringval = string;
+	  self->value.stringval = string.release ();
 	}
       break;
 
     case var_enum:
       {
 	int i;
-	char *str;
 
 	if (! gdbpy_is_string (value))
 	  {
@@ -171,13 +169,13 @@  set_parameter_value (parmpy_object *self, PyObject *value)
 	    return -1;
 	  }
 
-	str = python_string_to_host_string (value);
+	gdb::unique_xmalloc_ptr<char>
+	  str (python_string_to_host_string (value));
 	if (str == NULL)
 	  return -1;
 	for (i = 0; self->enumeration[i]; ++i)
-	  if (! strcmp (self->enumeration[i], str))
+	  if (! strcmp (self->enumeration[i], str.get ()))
 	    break;
-	xfree (str);
 	if (! self->enumeration[i])
 	  {
 	    PyErr_SetString (PyExc_RuntimeError,
@@ -301,10 +299,10 @@  set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
 /* A helper function which returns a documentation string for an
    object. */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 get_doc_string (PyObject *object, PyObject *attr)
 {
-  char *result = NULL;
+  gdb::unique_xmalloc_ptr<char> result;
 
   if (PyObject_HasAttr (object, attr))
     {
@@ -319,7 +317,7 @@  get_doc_string (PyObject *object, PyObject *attr)
       Py_XDECREF (ds_obj);
     }
   if (! result)
-    result = xstrdup (_("This command is not documented."));
+    result.reset (xstrdup (_("This command is not documented.")));
   return result;
 }
 
@@ -327,10 +325,10 @@  get_doc_string (PyObject *object, PyObject *attr)
    argument ARG.  ARG can be NULL.  METHOD should return a Python
    string.  If this function returns NULL, there has been an error and
    the appropriate exception set.  */
-static char *
+static gdb::unique_xmalloc_ptr<char>
 call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
 {
-  char *data = NULL;
+  gdb::unique_xmalloc_ptr<char> data;
   PyObject *result = PyObject_CallMethodObjArgs (obj, method, arg, NULL);
 
   if (! result)
@@ -365,7 +363,7 @@  get_set_value (char *args, int from_tty,
 	       struct cmd_list_element *c)
 {
   PyObject *obj = (PyObject *) get_cmd_context (c);
-  char *set_doc_string;
+  gdb::unique_xmalloc_ptr<char> set_doc_string;
   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
 					       current_language);
   PyObject *set_doc_func = PyString_FromString ("get_set_string");
@@ -387,8 +385,7 @@  get_set_value (char *args, int from_tty,
       set_doc_string  = get_doc_string (obj, set_doc_cst);
     }
 
-  make_cleanup (xfree, set_doc_string);
-  fprintf_filtered (gdb_stdout, "%s\n", set_doc_string);
+  fprintf_filtered (gdb_stdout, "%s\n", set_doc_string.get ());
 
   Py_XDECREF (set_doc_func);
   do_cleanups (cleanup);
@@ -413,7 +410,7 @@  get_show_value (struct ui_file *file, int from_tty,
 		const char *value)
 {
   PyObject *obj = (PyObject *) get_cmd_context (c);
-  char *show_doc_string = NULL;
+  gdb::unique_xmalloc_ptr<char> show_doc_string;
   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
 					       current_language);
   PyObject *show_doc_func = PyString_FromString ("get_show_string");
@@ -433,9 +430,7 @@  get_show_value (struct ui_file *file, int from_tty,
       if (! show_doc_string)
 	goto error;
 
-      make_cleanup (xfree, show_doc_string);
-
-      fprintf_filtered (file, "%s\n", show_doc_string);
+      fprintf_filtered (file, "%s\n", show_doc_string.get ());
     }
   else
     {
@@ -443,8 +438,7 @@  get_show_value (struct ui_file *file, int from_tty,
 	 callback function does not exist, then attempt to read the
 	 show_doc attribute.  */
       show_doc_string  = get_doc_string (obj, show_doc_cst);
-      make_cleanup (xfree, show_doc_string);
-      fprintf_filtered (file, "%s %s\n", show_doc_string, value);
+      fprintf_filtered (file, "%s %s\n", show_doc_string.get (), value);
     }
 
   Py_XDECREF (show_doc_func);
@@ -614,7 +608,7 @@  compute_enum_values (parmpy_object *self, PyObject *enum_values)
 			   _("The enumeration item not a string."));
 	  return 0;
 	}
-      self->enumeration[i] = python_string_to_host_string (item);
+      self->enumeration[i] = python_string_to_host_string (item).release ();
       Py_DECREF (item);
       if (self->enumeration[i] == NULL)
 	{
@@ -716,9 +710,9 @@  parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
   if (! cmd_name)
     return -1;
 
-  set_doc = get_doc_string (self, set_doc_cst);
-  show_doc = get_doc_string (self, show_doc_cst);
-  doc = get_doc_string (self, gdbpy_doc_cst);
+  set_doc = get_doc_string (self, set_doc_cst).release ();
+  show_doc = get_doc_string (self, show_doc_cst).release ();
+  doc = get_doc_string (self, gdbpy_doc_cst).release ();
 
   Py_INCREF (self);
 
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index 8834344..3c6a5af 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -244,11 +244,11 @@  pretty_print_one_value (PyObject *printer, struct value **out_value)
    NULL if there is no display_hint method, or if the method did not
    return a string.  On error, print stack trace and return NULL.  On
    success, return an xmalloc()d string.  */
-char *
+gdb::unique_xmalloc_ptr<char>
 gdbpy_get_display_hint (PyObject *printer)
 {
   PyObject *hint;
-  char *result = NULL;
+  gdb::unique_xmalloc_ptr<char> result;
 
   if (! PyObject_HasAttr (printer, gdbpy_display_hint_cst))
     return NULL;
@@ -279,20 +279,20 @@  print_stack_unless_memory_error (struct ui_file *stream)
     {
       struct cleanup *cleanup;
       PyObject *type, *value, *trace;
-      char *msg;
 
       PyErr_Fetch (&type, &value, &trace);
       cleanup = make_cleanup_py_decref (type);
       make_cleanup_py_decref (value);
       make_cleanup_py_decref (trace);
 
-      msg = gdbpy_exception_to_string (type, value);
-      make_cleanup (xfree, msg);
+      gdb::unique_xmalloc_ptr<char>
+	msg (gdbpy_exception_to_string (type, value));
 
       if (msg == NULL || *msg == '\0')
 	fprintf_filtered (stream, _("<error reading variable>"));
       else
-	fprintf_filtered (stream, _("<error reading variable: %s>"), msg);
+	fprintf_filtered (stream, _("<error reading variable: %s>"),
+			  msg.get ());
 
       do_cleanups (cleanup);
     }
@@ -647,16 +647,13 @@  print_children (PyObject *printer, const char *hint,
 	}
       else if (gdbpy_is_string (py_v))
 	{
-	  char *output;
+	  gdb::unique_xmalloc_ptr<char> output;
 
 	  output = python_string_to_host_string (py_v);
 	  if (!output)
 	    gdbpy_print_stack ();
 	  else
-	    {
-	      fputs_filtered (output, stream);
-	      xfree (output);
-	    }
+	    fputs_filtered (output.get (), stream);
 	}
       else
 	{
@@ -713,7 +710,7 @@  gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
   PyObject *printer = NULL;
   PyObject *val_obj = NULL;
   struct value *value;
-  char *hint = NULL;
+  gdb::unique_xmalloc_ptr<char> hint;
   struct cleanup *cleanups;
   enum ext_lang_rc result = EXT_LANG_RC_NOP;
   enum string_repr_result print_result;
@@ -767,13 +764,12 @@  gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
 
   /* If we are printing a map, we want some special formatting.  */
   hint = gdbpy_get_display_hint (printer);
-  make_cleanup (free_current_contents, &hint);
 
   /* Print the section */
-  print_result = print_string_repr (printer, hint, stream, recurse,
+  print_result = print_string_repr (printer, hint.get (), stream, recurse,
 				    options, language, gdbarch);
   if (print_result != string_repr_error)
-    print_children (printer, hint, stream, recurse, options, language,
+    print_children (printer, hint.get (), stream, recurse, options, language,
 		    print_result == string_repr_none);
 
   result = EXT_LANG_RC_OK;
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 03cc8d9..d33d44d 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1199,10 +1199,9 @@  static PyObject *
 typy_getitem (PyObject *self, PyObject *key)
 {
   struct type *type = ((type_object *) self)->type;
-  char *field;
   int i;
 
-  field = python_string_to_host_string (key);
+  gdb::unique_xmalloc_ptr<char> field = python_string_to_host_string (key);
   if (field == NULL)
     return NULL;
 
@@ -1218,7 +1217,7 @@  typy_getitem (PyObject *self, PyObject *key)
     {
       const char *t_field_name = TYPE_FIELD_NAME (type, i);
 
-      if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
+      if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0))
 	{
 	  return convert_field (type, i);
 	}
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index cc685ae..b392c46 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -116,12 +116,12 @@  pyuw_parse_register_id (struct gdbarch *gdbarch, PyObject *pyo_reg_id,
     return 0;
   if (gdbpy_is_string (pyo_reg_id))
     {
-      const char *reg_name = gdbpy_obj_to_string (pyo_reg_id);
+      gdb::unique_xmalloc_ptr<char> reg_name (gdbpy_obj_to_string (pyo_reg_id));
 
       if (reg_name == NULL)
         return 0;
-      *reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name,
-                                              strlen (reg_name));
+      *reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name.get (),
+                                              strlen (reg_name.get ()));
       return *reg_num >= 0;
     }
   else if (PyInt_Check (pyo_reg_id))
diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c
index 2e2121d..9f99e29 100644
--- a/gdb/python/py-utils.c
+++ b/gdb/python/py-utils.c
@@ -107,10 +107,10 @@  python_string_to_unicode (PyObject *obj)
    conversion, NULL will be returned and a python exception will be set.
 
    The caller is responsible for xfree'ing the string.  */
-static char *
+static gdb::unique_xmalloc_ptr<char>
 unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
 {
-  char *result;
+  gdb::unique_xmalloc_ptr<char> result;
   PyObject *string;
 
   /* Translate string to named charset.  */
@@ -119,9 +119,9 @@  unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
     return NULL;
 
 #ifdef IS_PY3K
-  result = xstrdup (PyBytes_AsString (string));
+  result.reset (xstrdup (PyBytes_AsString (string)));
 #else
-  result = xstrdup (PyString_AsString (string));
+  result.reset (xstrdup (PyString_AsString (string)));
 #endif
 
   Py_DECREF (string);
@@ -140,12 +140,11 @@  unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
   return PyUnicode_AsEncodedString (unicode_str, charset, NULL);
 }
 
-/* Returns a newly allocated string with the contents of the given unicode
-   string object converted to the target's charset.  If an error occurs during
-   the conversion, NULL will be returned and a python exception will be set.
-
-   The caller is responsible for xfree'ing the string.  */
-char *
+/* Returns a newly allocated string with the contents of the given
+   unicode string object converted to the target's charset.  If an
+   error occurs during the conversion, NULL will be returned and a
+   python exception will be set.  */
+gdb::unique_xmalloc_ptr<char>
 unicode_to_target_string (PyObject *unicode_str)
 {
   return unicode_to_encoded_string (unicode_str,
@@ -164,20 +163,18 @@  unicode_to_target_python_string (PyObject *unicode_str)
 }
 
 /* Converts a python string (8-bit or unicode) to a target string in
-   the target's charset.  Returns NULL on error, with a python exception set.
-
-   The caller is responsible for xfree'ing the string.  */
-char *
+   the target's charset.  Returns NULL on error, with a python
+   exception set.  */
+gdb::unique_xmalloc_ptr<char>
 python_string_to_target_string (PyObject *obj)
 {
   PyObject *str;
-  char *result;
 
   str = python_string_to_unicode (obj);
   if (str == NULL)
     return NULL;
 
-  result = unicode_to_target_string (str);
+  gdb::unique_xmalloc_ptr<char> result (unicode_to_target_string (str));
   Py_DECREF (str);
   return result;
 }
@@ -203,20 +200,19 @@  python_string_to_target_python_string (PyObject *obj)
 }
 
 /* Converts a python string (8-bit or unicode) to a target string in
-   the host's charset.  Returns NULL on error, with a python exception set.
-
-   The caller is responsible for xfree'ing the string.  */
-char *
+   the host's charset.  Returns NULL on error, with a python exception
+   set.  */
+gdb::unique_xmalloc_ptr<char>
 python_string_to_host_string (PyObject *obj)
 {
   PyObject *str;
-  char *result;
 
   str = python_string_to_unicode (obj);
   if (str == NULL)
     return NULL;
 
-  result = unicode_to_encoded_string (str, host_charset ());
+  gdb::unique_xmalloc_ptr<char>
+    result (unicode_to_encoded_string (str, host_charset ()));
   Py_DECREF (str);
   return result;
 }
@@ -243,20 +239,21 @@  gdbpy_is_string (PyObject *obj)
 }
 
 /* Return the string representation of OBJ, i.e., str (obj).
-   Space for the result is malloc'd, the caller must free.
    If the result is NULL a python error occurred, the caller must clear it.  */
 
-char *
+gdb::unique_xmalloc_ptr<char>
 gdbpy_obj_to_string (PyObject *obj)
 {
   PyObject *str_obj = PyObject_Str (obj);
 
   if (str_obj != NULL)
     {
+      gdb::unique_xmalloc_ptr<char> msg;
+
 #ifdef IS_PY3K
-      char *msg = python_string_to_host_string (str_obj);
+      msg = python_string_to_host_string (str_obj);
 #else
-      char *msg = xstrdup (PyString_AsString (str_obj));
+      msg.reset (xstrdup (PyString_AsString (str_obj)));
 #endif
 
       Py_DECREF (str_obj);
@@ -269,14 +266,11 @@  gdbpy_obj_to_string (PyObject *obj)
 /* Return the string representation of the exception represented by
    TYPE, VALUE which is assumed to have been obtained with PyErr_Fetch,
    i.e., the error indicator is currently clear.
-   Space for the result is malloc'd, the caller must free.
    If the result is NULL a python error occurred, the caller must clear it.  */
 
-char *
+gdb::unique_xmalloc_ptr<char>
 gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue)
 {
-  char *str;
-
   /* There are a few cases to consider.
      For example:
      pvalue is a string when PyErr_SetString is used.
@@ -288,11 +282,9 @@  gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue)
      gdb.GdbError ("message").  */
 
   if (pvalue && pvalue != Py_None)
-    str = gdbpy_obj_to_string (pvalue);
+    return gdbpy_obj_to_string (pvalue);
   else
-    str = gdbpy_obj_to_string (ptype);
-
-  return str;
+    return gdbpy_obj_to_string (ptype);
 }
 
 /* Convert a GDB exception to the appropriate Python exception.
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 46683b8..3a6d431 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -667,7 +667,7 @@  valpy_getitem (PyObject *self, PyObject *key)
 {
   struct gdb_exception except = exception_none;
   value_object *self_value = (value_object *) self;
-  char *field = NULL;
+  gdb::unique_xmalloc_ptr<char> field;
   struct type *base_class_type = NULL, *field_type = NULL;
   long bitpos = -1;
   PyObject *result = NULL;
@@ -754,7 +754,7 @@  valpy_getitem (PyObject *self, PyObject *key)
       struct value *res_val = NULL;
 
       if (field)
-	res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
+	res_val = value_struct_elt (&tmp, NULL, field.get (), 0, NULL);
       else if (bitpos >= 0)
 	res_val = value_struct_elt_bitpos (&tmp, bitpos, field_type,
 					   "struct/class/union");
@@ -803,7 +803,6 @@  valpy_getitem (PyObject *self, PyObject *key)
     }
   END_CATCH
 
-  xfree (field);
   GDB_PY_HANDLE_EXCEPTION (except);
 
   return result;
@@ -1663,17 +1662,11 @@  convert_value_from_python (PyObject *obj)
 	}
       else if (gdbpy_is_string (obj))
 	{
-	  char *s;
-
-	  s = python_string_to_target_string (obj);
+	  gdb::unique_xmalloc_ptr<char> s
+	    = python_string_to_target_string (obj);
 	  if (s != NULL)
-	    {
-	      struct cleanup *old;
-
-	      old = make_cleanup (xfree, s);
-	      value = value_cstring (s, strlen (s), builtin_type_pychar);
-	      do_cleanups (old);
-	    }
+	    value = value_cstring (s.get (), strlen (s.get ()),
+				   builtin_type_pychar);
 	}
       else if (PyObject_TypeCheck (obj, &value_object_type))
 	value = value_copy (((value_object *) obj)->value);
diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index 7e74454..3bb96d7 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -75,10 +75,11 @@  py_varobj_iter_next (struct varobj_iter *self)
       if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
 	{
 	  PyObject *type, *value, *trace;
-	  char *name_str, *value_str;
+	  char *name_str;
 
 	  PyErr_Fetch (&type, &value, &trace);
-	  value_str = gdbpy_exception_to_string (type, value);
+	  gdb::unique_xmalloc_ptr<char>
+	    value_str (gdbpy_exception_to_string (type, value));
 	  Py_XDECREF (type);
 	  Py_XDECREF (value);
 	  Py_XDECREF (trace);
@@ -90,9 +91,8 @@  py_varobj_iter_next (struct varobj_iter *self)
 
 	  name_str = xstrprintf ("<error at %d>",
 				 self->next_raw_index++);
-	  item = Py_BuildValue ("(ss)", name_str, value_str);
+	  item = Py_BuildValue ("(ss)", name_str, value_str.get ());
 	  xfree (name_str);
-	  xfree (value_str);
 	  if (item == NULL)
 	    {
 	      gdbpy_print_stack ();
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 8545c7b..f3213bb 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -533,14 +533,15 @@  int gdbpy_print_python_errors_p (void);
 void gdbpy_print_stack (void);
 
 PyObject *python_string_to_unicode (PyObject *obj);
-char *unicode_to_target_string (PyObject *unicode_str);
-char *python_string_to_target_string (PyObject *obj);
+gdb::unique_xmalloc_ptr<char> unicode_to_target_string (PyObject *unicode_str);
+gdb::unique_xmalloc_ptr<char> python_string_to_target_string (PyObject *obj);
 PyObject *python_string_to_target_python_string (PyObject *obj);
-char *python_string_to_host_string (PyObject *obj);
+gdb::unique_xmalloc_ptr<char> python_string_to_host_string (PyObject *obj);
 PyObject *host_string_to_python_string (const char *str);
 int gdbpy_is_string (PyObject *obj);
-char *gdbpy_obj_to_string (PyObject *obj);
-char *gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue);
+gdb::unique_xmalloc_ptr<char> gdbpy_obj_to_string (PyObject *obj);
+gdb::unique_xmalloc_ptr<char> gdbpy_exception_to_string (PyObject *ptype,
+							 PyObject *pvalue);
 
 int gdbpy_is_lazy_string (PyObject *result);
 void gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
@@ -555,7 +556,7 @@  PyObject *apply_varobj_pretty_printer (PyObject *print_obj,
 				       struct value **replacement,
 				       struct ui_file *stream);
 PyObject *gdbpy_get_varobj_pretty_printer (struct value *value);
-char *gdbpy_get_display_hint (PyObject *printer);
+gdb::unique_xmalloc_ptr<char> gdbpy_get_display_hint (PyObject *printer);
 PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args);
 
 void bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index d6bd6bf..f354601 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1027,7 +1027,7 @@  gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
 			  const char *current_gdb_prompt)
 {
   struct cleanup *cleanup;
-  char *prompt = NULL;
+  gdb::unique_xmalloc_ptr<char> prompt;
 
   if (!gdb_python_initialized)
     return EXT_LANG_RC_NOP;
@@ -1080,8 +1080,6 @@  gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
 
 	      if (prompt == NULL)
 		goto fail;
-	      else
-		make_cleanup (xfree, prompt);
 	    }
 	}
     }
@@ -1089,7 +1087,7 @@  gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
   /* If a prompt has been set, PROMPT will not be NULL.  If it is
      NULL, do not set the prompt.  */
   if (prompt != NULL)
-    set_prompt (prompt);
+    set_prompt (prompt.get ());
 
   do_cleanups (cleanup);
   return prompt != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_NOP;
@@ -1220,13 +1218,13 @@  gdbpy_print_stack (void)
   else
     {
       PyObject *ptype, *pvalue, *ptraceback;
-      char *msg = NULL, *type = NULL;
 
       PyErr_Fetch (&ptype, &pvalue, &ptraceback);
 
       /* Fetch the error message contained within ptype, pvalue.  */
-      msg = gdbpy_exception_to_string (ptype, pvalue);
-      type = gdbpy_obj_to_string (ptype);
+      gdb::unique_xmalloc_ptr<char>
+	msg (gdbpy_exception_to_string (ptype, pvalue));
+      gdb::unique_xmalloc_ptr<char> type (gdbpy_obj_to_string (ptype));
 
       TRY
 	{
@@ -1240,7 +1238,7 @@  gdbpy_print_stack (void)
 	    }
 	  else
 	    fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n",
-			      type, msg);
+			      type.get (), msg.get ());
 	}
       CATCH (except, RETURN_MASK_ALL)
 	{
@@ -1250,7 +1248,6 @@  gdbpy_print_stack (void)
       Py_XDECREF (ptype);
       Py_XDECREF (pvalue);
       Py_XDECREF (ptraceback);
-      xfree (msg);
     }
 }
 
@@ -1455,7 +1452,7 @@  gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
   PyObject *type_obj, *type_module = NULL, *func = NULL;
   PyObject *result_obj = NULL;
   PyObject *printers_obj = (PyObject *) ext_printers->py_type_printers;
-  char *result = NULL;
+  gdb::unique_xmalloc_ptr<char> result;
 
   if (printers_obj == NULL)
     return EXT_LANG_RC_NOP;
@@ -1508,8 +1505,11 @@  gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
   Py_XDECREF (result_obj);
   do_cleanups (cleanups);
   if (result != NULL)
-    *prettied_type = result;
-  return result != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_ERROR;
+    {
+      *prettied_type = result.release ();
+      return EXT_LANG_RC_OK;
+    }
+  return EXT_LANG_RC_ERROR;
 }
 
 /* Free the result of start_type_printers.
diff --git a/gdb/varobj.c b/gdb/varobj.c
index fb1349a..8a6cb06 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -558,10 +558,10 @@  varobj_get_display_format (const struct varobj *var)
   return var->format;
 }
 
-char *
+gdb::unique_xmalloc_ptr<char>
 varobj_get_display_hint (const struct varobj *var)
 {
-  char *result = NULL;
+  gdb::unique_xmalloc_ptr<char> result;
 
 #if HAVE_PYTHON
   struct cleanup *back_to;
@@ -2512,26 +2512,26 @@  varobj_value_get_print_value (struct value *value,
 			 string_print.  Otherwise just return the extracted
 			 string as a value.  */
 
-		      char *s = python_string_to_target_string (output);
+		      gdb::unique_xmalloc_ptr<char> s
+			= python_string_to_target_string (output);
 
 		      if (s)
 			{
 			  struct gdbarch *gdbarch;
-			  char *hint;
 
-			  hint = gdbpy_get_display_hint (value_formatter);
+			  gdb::unique_xmalloc_ptr<char> hint
+			    = gdbpy_get_display_hint (value_formatter);
 			  if (hint)
 			    {
-			      if (!strcmp (hint, "string"))
+			      if (!strcmp (hint.get (), "string"))
 				string_print = 1;
-			      xfree (hint);
 			    }
 
-			  len = strlen (s);
-			  thevalue = (char *) xmemdup (s, len + 1, len + 1);
+			  len = strlen (s.get ());
+			  thevalue = (char *) xmemdup (s.get (), len + 1,
+						       len + 1);
 			  gdbarch = get_type_arch (value_type (value));
 			  type = builtin_type (gdbarch)->builtin_char;
-			  xfree (s);
 
 			  if (!string_print)
 			    {
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 6b9a71f..92d79bb 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -268,7 +268,8 @@  extern void varobj_get_child_range (const struct varobj *var, int *from,
 
 extern void varobj_set_child_range (struct varobj *var, int from, int to);
 
-extern char *varobj_get_display_hint (const struct varobj *var);
+extern gdb::unique_xmalloc_ptr<char>
+     varobj_get_display_hint (const struct varobj *var);
 
 extern int varobj_get_num_children (struct varobj *var);