diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index af874df..fe99b47 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
 2017-09-10  Tom Tromey  <tom@tromey.com>
 
+	* ada-lang.c (is_known_support_routine): Update.
+	(ada_unhandled_exception_name_addr_from_raise): Update.
+	* guile/scm-frame.c (gdbscm_frame_name): Update.
+	* python/py-frame.c (frapy_name): Update.
+	(frapy_function): Update.
+	* stack.h (find_frame_funname): Update.
+	* stack.c (find_frame_funname): Return unique_xmalloc_ptr.
+	(print_frame): Update.
+
+2017-09-10  Tom Tromey  <tom@tromey.com>
+
 	* findcmd.c (put_bits): Take a gdb::byte_vector.
 	(parse_find_args): Return gdb::byte_vector.  "args" now const.
 	Remove "pattern_bufp" and "pattern_lenp" parameters.  Remove
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index fdc2a90..3a46831 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11979,7 +11979,6 @@ ada_exception_support_info_sniffer (void)
 static int
 is_known_support_routine (struct frame_info *frame)
 {
-  char *func_name;
   enum language func_lang;
   int i;
   const char *fullname;
@@ -12018,21 +12017,18 @@ is_known_support_routine (struct frame_info *frame)
 
   /* Check whether the function is a GNAT-generated entity.  */
 
-  find_frame_funname (frame, &func_name, &func_lang, NULL);
+  gdb::unique_xmalloc_ptr<char> func_name
+    = find_frame_funname (frame, &func_lang, NULL);
   if (func_name == NULL)
     return 1;
 
   for (i = 0; known_auxiliary_function_name_patterns[i] != NULL; i += 1)
     {
       re_comp (known_auxiliary_function_name_patterns[i]);
-      if (re_exec (func_name))
-	{
-	  xfree (func_name);
-	  return 1;
-	}
+      if (re_exec (func_name.get ()))
+	return 1;
     }
 
-  xfree (func_name);
   return 0;
 }
 
@@ -12076,7 +12072,6 @@ ada_unhandled_exception_name_addr_from_raise (void)
   int frame_level;
   struct frame_info *fi;
   struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
-  struct cleanup *old_chain;
 
   /* To determine the name of this exception, we need to select
      the frame corresponding to RAISE_SYM_NAME.  This frame is
@@ -12087,24 +12082,20 @@ ada_unhandled_exception_name_addr_from_raise (void)
     if (fi != NULL)
       fi = get_prev_frame (fi); 
 
-  old_chain = make_cleanup (null_cleanup, NULL);
   while (fi != NULL)
     {
-      char *func_name;
       enum language func_lang;
 
-      find_frame_funname (fi, &func_name, &func_lang, NULL);
+      gdb::unique_xmalloc_ptr<char> func_name
+	= find_frame_funname (fi, &func_lang, NULL);
       if (func_name != NULL)
 	{
-	  make_cleanup (xfree, func_name);
-
-          if (strcmp (func_name,
+          if (strcmp (func_name.get (),
 		      data->exception_info->catch_exception_sym) == 0)
 	    break; /* We found the frame we were looking for...  */
 	  fi = get_prev_frame (fi);
 	}
     }
-  do_cleanups (old_chain);
 
   if (fi == NULL)
     return 0;
diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c
index b2af743..f504a88 100644
--- a/gdb/guile/scm-frame.c
+++ b/gdb/guile/scm-frame.c
@@ -418,7 +418,7 @@ static SCM
 gdbscm_frame_name (SCM self)
 {
   frame_smob *f_smob;
-  char *name = NULL;
+  gdb::unique_xmalloc_ptr<char> name;
   enum language lang = language_minimal;
   struct frame_info *frame = NULL;
   SCM result;
@@ -429,11 +429,10 @@ gdbscm_frame_name (SCM self)
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
-	find_frame_funname (frame, &name, &lang, NULL);
+	name = find_frame_funname (frame, &lang, NULL);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      xfree (name);
       GDBSCM_HANDLE_GDB_EXCEPTION (except);
     }
   END_CATCH
@@ -446,8 +445,7 @@ gdbscm_frame_name (SCM self)
 
   if (name != NULL)
     {
-      result = gdbscm_scm_from_c_string (name);
-      xfree (name);
+      result = gdbscm_scm_from_c_string (name.get ());
     }
   else
     result = SCM_BOOL_F;
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index c5ae391..a927b3c 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -119,7 +119,7 @@ static PyObject *
 frapy_name (PyObject *self, PyObject *args)
 {
   struct frame_info *frame;
-  char *name = NULL;
+  gdb::unique_xmalloc_ptr<char> name;
   enum language lang;
   PyObject *result;
 
@@ -127,19 +127,18 @@ frapy_name (PyObject *self, PyObject *args)
     {
       FRAPY_REQUIRE_VALID (self, frame);
 
-      find_frame_funname (frame, &name, &lang, NULL);
+      name = find_frame_funname (frame, &lang, NULL);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      xfree (name);
       GDB_PY_HANDLE_EXCEPTION (except);
     }
   END_CATCH
 
   if (name)
     {
-      result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
-      xfree (name);
+      result = PyUnicode_Decode (name.get (), strlen (name.get ()),
+				 host_charset (), NULL);
     }
   else
     {
@@ -334,13 +333,12 @@ frapy_function (PyObject *self, PyObject *args)
 
   TRY
     {
-      char *funname;
       enum language funlang;
 
       FRAPY_REQUIRE_VALID (self, frame);
 
-      find_frame_funname (frame, &funname, &funlang, &sym);
-      xfree (funname);
+      gdb::unique_xmalloc_ptr<char> funname
+	= find_frame_funname (frame, &funlang, &sym);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/stack.c b/gdb/stack.c
index 2433009..2dae380 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1032,16 +1032,16 @@ get_last_displayed_sal ()
 }
 
 
-/* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
-   corresponding to FRAME.  FUNNAME needs to be freed by the caller.  */
+/* Attempt to obtain the name, FUNLANG and optionally FUNCP of the function
+   corresponding to FRAME.  */
 
-void
-find_frame_funname (struct frame_info *frame, char **funname,
-		    enum language *funlang, struct symbol **funcp)
+gdb::unique_xmalloc_ptr<char>
+find_frame_funname (struct frame_info *frame, enum language *funlang,
+		    struct symbol **funcp)
 {
   struct symbol *func;
+  gdb::unique_xmalloc_ptr<char> funname;
 
-  *funname = NULL;
   *funlang = language_unknown;
   if (funcp)
     *funcp = NULL;
@@ -1084,7 +1084,7 @@ find_frame_funname (struct frame_info *frame, char **funname,
 	  /* We also don't know anything about the function besides
 	     its address and name.  */
 	  func = 0;
-	  *funname = xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym));
+	  funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
 	  *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
 	}
       else
@@ -1104,14 +1104,13 @@ find_frame_funname (struct frame_info *frame, char **funname,
 	      char *func_only = cp_remove_params (print_name);
 
 	      if (func_only)
-		*funname = func_only;
+		funname.reset (func_only);
 	    }
 
-	  /* If we didn't hit the C++ case above, set *funname here.
-	     This approach is taken to avoid having to install a
-	     cleanup in case cp_remove_params can throw.  */
-	  if (*funname == NULL)
-	    *funname = xstrdup (print_name);
+	  /* If we didn't hit the C++ case above, set *funname
+	     here.  */
+	  if (funname == NULL)
+	    funname.reset (xstrdup (print_name));
 	}
     }
   else
@@ -1120,15 +1119,17 @@ find_frame_funname (struct frame_info *frame, char **funname,
       CORE_ADDR pc;
 
       if (!get_frame_address_in_block_if_available (frame, &pc))
-	return;
+	return funname;
 
       msymbol = lookup_minimal_symbol_by_pc (pc);
       if (msymbol.minsym != NULL)
 	{
-	  *funname = xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym));
+	  funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
 	  *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
 	}
     }
+
+  return funname;
 }
 
 static void
@@ -1138,9 +1139,7 @@ print_frame (struct frame_info *frame, int print_level,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct ui_out *uiout = current_uiout;
-  char *funname = NULL;
   enum language funlang = language_unknown;
-  struct cleanup *old_chain;
   struct value_print_options opts;
   struct symbol *func;
   CORE_ADDR pc = 0;
@@ -1148,9 +1147,8 @@ print_frame (struct frame_info *frame, int print_level,
 
   pc_p = get_frame_pc_if_available (frame, &pc);
 
-
-  find_frame_funname (frame, &funname, &funlang, &func);
-  old_chain = make_cleanup (xfree, funname);
+  gdb::unique_xmalloc_ptr<char> funname
+    = find_frame_funname (frame, &funlang, &func);
 
   annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
 			gdbarch, pc);
@@ -1181,7 +1179,7 @@ print_frame (struct frame_info *frame, int print_level,
     annotate_frame_function_name ();
 
     string_file stb;
-    fprintf_symbol_filtered (&stb, funname ? funname : "??",
+    fprintf_symbol_filtered (&stb, funname ? funname.get () : "??",
 			     funlang, DMGL_ANSI);
     uiout->field_stream ("func", stb);
     uiout->wrap_hint ("   ");
@@ -1257,7 +1255,6 @@ print_frame (struct frame_info *frame, int print_level,
   }
 
   uiout->text ("\n");
-  do_cleanups (old_chain);
 }
 
 
diff --git a/gdb/stack.h b/gdb/stack.h
index f41d21e..3379318 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -22,8 +22,9 @@
 
 void select_frame_command (char *level_exp, int from_tty);
 
-void find_frame_funname (struct frame_info *frame, char **funname,
-			 enum language *funlang, struct symbol **funcp);
+gdb::unique_xmalloc_ptr<char> find_frame_funname (struct frame_info *frame,
+						  enum language *funlang,
+						  struct symbol **funcp);
 
 typedef void (*iterate_over_block_arg_local_vars_cb) (const char *print_name,
 						      struct symbol *sym,
