Patchwork [RFA] Use gdb::unique_xmalloc_ptr when calling tilde_expand

login
register
mail settings
Submitter Tom Tromey
Date Aug. 5, 2017, 4:25 p.m.
Message ID <877eyi7zj6.fsf@tromey.com>
Download mbox | patch
Permalink /patch/21932/
State New
Headers show

Comments

Tom Tromey - Aug. 5, 2017, 4:25 p.m.
Simon> I don't see any reason either.

Thanks.  Here's v3.

Tom

commit 425513c1f13aa923cc025490dbc05ed6333b4b00
Author: Tom Tromey <tom@tromey.com>
Date:   Mon Jul 31 15:49:21 2017 -0600

    Use gdb::unique_xmalloc_ptr when calling tilde_expand
    
    This patch changes most sites calling tilde_expand to use
    gdb::unique_xmalloc_ptr, rather than a cleanup.  It also changes
    scan_expression_with_cleanup to return a unique pointer, because the
    patch was already touching code in that area.
    
    Regression tested on the buildbot.
    
    2017-08-04  Tom Tromey  <tom@tromey.com>
    
            * compile/compile-object-load.c (compile_object_load): Use
            gdb::unique_xmalloc_ptr.
            * cli/cli-dump.c (scan_filename): Rename from
            scan_filename_with_cleanup.  Change return type.
            (scan_expression): Rename from scan_expression_with_cleanup.
            Change return type.
            (dump_memory_to_file, dump_value_to_file, restore_command):
            Use gdb::unique_xmalloc_ptr.  Update.
            * cli/cli-cmds.c (find_and_open_script): Use
            gdb::unique_xmalloc_ptr.
            * tracefile-tfile.c (tfile_open): Use gdb::unique_xmalloc_ptr.
            * symmisc.c (maintenance_print_symbols)
            (maintenance_print_msymbols): Use gdb::unique_xmalloc_ptr.
            * symfile.c (symfile_bfd_open, generic_load)
            (add_symbol_file_command, remove_symbol_file_command): Use
            gdb::unique_xmalloc_ptr.
            * source.c (openp): Use gdb::unique_xmalloc_ptr.
            * psymtab.c (maintenance_print_psymbols): Use
            gdb::unique_xmalloc_ptr.
            * corelow.c (core_open): Use gdb::unique_xmalloc_ptr.
            * breakpoint.c (save_breakpoints): Use gdb::unique_xmalloc_ptr.
            * solib.c (solib_map_sections): Use gdb::unique_xmalloc_ptr.
            (reload_shared_libraries_1): Likewise.
Simon Marchi - Aug. 5, 2017, 4:40 p.m.
On 2017-08-05 18:25, Tom Tromey wrote:
> Simon> I don't see any reason either.
> 
> Thanks.  Here's v3.
> 
> Tom

Again, I just looked at solib.c.  It LGTM.

Simon

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 92c573d..d1e3d8a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,29 @@ 
+2017-08-04  Tom Tromey  <tom@tromey.com>
+
+	* compile/compile-object-load.c (compile_object_load): Use
+	gdb::unique_xmalloc_ptr.
+	* cli/cli-dump.c (scan_filename): Rename from
+	scan_filename_with_cleanup.  Change return type.
+	(scan_expression): Rename from scan_expression_with_cleanup.
+	Change return type.
+	(dump_memory_to_file, dump_value_to_file, restore_command):
+	Use gdb::unique_xmalloc_ptr.  Update.
+	* cli/cli-cmds.c (find_and_open_script): Use
+	gdb::unique_xmalloc_ptr.
+	* tracefile-tfile.c (tfile_open): Use gdb::unique_xmalloc_ptr.
+	* symmisc.c (maintenance_print_symbols)
+	(maintenance_print_msymbols): Use gdb::unique_xmalloc_ptr.
+	* symfile.c (symfile_bfd_open, generic_load)
+	(add_symbol_file_command, remove_symbol_file_command): Use
+	gdb::unique_xmalloc_ptr.
+	* source.c (openp): Use gdb::unique_xmalloc_ptr.
+	* psymtab.c (maintenance_print_psymbols): Use
+	gdb::unique_xmalloc_ptr.
+	* corelow.c (core_open): Use gdb::unique_xmalloc_ptr.
+	* breakpoint.c (save_breakpoints): Use gdb::unique_xmalloc_ptr.
+	* solib.c (solib_map_sections): Use gdb::unique_xmalloc_ptr.
+	(reload_shared_libraries_1): Likewise.
+
 2017-08-03  Tom Tromey  <tom@tromey.com>
 
 	* utils.c (make_cleanup_freeargv, do_freeargv, gdb_buildargv):
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index de6df2e..3dc9112 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -15478,7 +15478,6 @@  save_breakpoints (char *filename, int from_tty,
 {
   struct breakpoint *tp;
   int any = 0;
-  struct cleanup *cleanup;
   int extra_trace_bits = 0;
 
   if (filename == 0 || *filename == 0)
@@ -15512,14 +15511,13 @@  save_breakpoints (char *filename, int from_tty,
       return;
     }
 
-  filename = tilde_expand (filename);
-  cleanup = make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> expanded_filename (tilde_expand (filename));
 
   stdio_file fp;
 
-  if (!fp.open (filename, "w"))
+  if (!fp.open (expanded_filename.get (), "w"))
     error (_("Unable to open file '%s' for saving (%s)"),
-	   filename, safe_strerror (errno));
+	   expanded_filename.get (), safe_strerror (errno));
 
   if (extra_trace_bits)
     save_trace_state_variables (&fp);
@@ -15587,8 +15585,7 @@  save_breakpoints (char *filename, int from_tty,
     fp.printf ("set default-collect %s\n", default_collect);
 
   if (from_tty)
-    printf_filtered (_("Saved to file '%s'.\n"), filename);
-  do_cleanups (cleanup);
+    printf_filtered (_("Saved to file '%s'.\n"), expanded_filename.get ());
 }
 
 /* The `save breakpoints' command.  */
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 036a2f0..d3ec4ae 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -516,14 +516,11 @@  show_script_ext_mode (struct ui_file *file, int from_tty,
 gdb::optional<open_script>
 find_and_open_script (const char *script_file, int search_path)
 {
-  char *file;
   int fd;
-  struct cleanup *old_cleanups;
   int search_flags = OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH;
   gdb::optional<open_script> opened;
 
-  file = tilde_expand (script_file);
-  old_cleanups = make_cleanup (xfree, file);
+  gdb::unique_xmalloc_ptr<char> file (tilde_expand (script_file));
 
   if (search_path)
     search_flags |= OPF_SEARCH_IN_PATH;
@@ -532,18 +529,11 @@  find_and_open_script (const char *script_file, int search_path)
      files.  Put the full location in *FULL_PATHP.  */
   char *temp_path;
   fd = openp (source_path, search_flags,
-	      file, O_RDONLY, &temp_path);
+	      file.get (), O_RDONLY, &temp_path);
   gdb::unique_xmalloc_ptr<char> full_path (temp_path);
 
   if (fd == -1)
-    {
-      int save_errno = errno;
-      do_cleanups (old_cleanups);
-      errno = save_errno;
-      return opened;
-    }
-
-  do_cleanups (old_cleanups);
+    return opened;
 
   FILE *result = fdopen (fd, FOPEN_RT);
   if (result == NULL)
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index 6d55a02..30897d8 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -33,16 +33,11 @@ 
 #include "filestuff.h"
 #include "common/byte-vector.h"
 
-static const char *
-scan_expression_with_cleanup (const char **cmd, const char *def)
+static gdb::unique_xmalloc_ptr<char>
+scan_expression (const char **cmd, const char *def)
 {
   if ((*cmd) == NULL || (**cmd) == '\0')
-    {
-      char *exp = xstrdup (def);
-
-      make_cleanup (xfree, exp);
-      return exp;
-    }
+    return gdb::unique_xmalloc_ptr<char> (xstrdup (def));
   else
     {
       char *exp;
@@ -50,17 +45,16 @@  scan_expression_with_cleanup (const char **cmd, const char *def)
 
       end = (*cmd) + strcspn (*cmd, " \t");
       exp = savestring ((*cmd), end - (*cmd));
-      make_cleanup (xfree, exp);
       (*cmd) = skip_spaces_const (end);
-      return exp;
+      return gdb::unique_xmalloc_ptr<char> (exp);
     }
 }
 
 
-static char *
-scan_filename_with_cleanup (const char **cmd, const char *defname)
+static gdb::unique_xmalloc_ptr<char>
+scan_filename (const char **cmd, const char *defname)
 {
-  char *filename;
+  gdb::unique_xmalloc_ptr<char> filename;
   char *fullname;
 
   /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere.  */
@@ -70,8 +64,7 @@  scan_filename_with_cleanup (const char **cmd, const char *defname)
     {
       if (defname == NULL)
 	error (_("Missing filename."));
-      filename = xstrdup (defname);
-      make_cleanup (xfree, filename);
+      filename.reset (xstrdup (defname));
     }
   else
     {
@@ -80,16 +73,12 @@  scan_filename_with_cleanup (const char **cmd, const char *defname)
 
       (*cmd) = skip_spaces_const (*cmd);
       end = *cmd + strcspn (*cmd, " \t");
-      filename = savestring ((*cmd), end - (*cmd));
-      make_cleanup (xfree, filename);
+      filename.reset (savestring ((*cmd), end - (*cmd)));
       (*cmd) = skip_spaces_const (end);
     }
   gdb_assert (filename != NULL);
 
-  fullname = tilde_expand (filename);
-  make_cleanup (xfree, fullname);
-  
-  return fullname;
+  return gdb::unique_xmalloc_ptr<char> (tilde_expand (filename.get ()));
 }
 
 static gdb_bfd_ref_ptr
@@ -189,28 +178,25 @@  dump_bfd_file (const char *filename, const char *mode,
 static void
 dump_memory_to_file (const char *cmd, const char *mode, const char *file_format)
 {
-  struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
   CORE_ADDR lo;
   CORE_ADDR hi;
   ULONGEST count;
-  const char *filename;
-  const char *lo_exp;
   const char *hi_exp;
 
   /* Open the file.  */
-  filename = scan_filename_with_cleanup (&cmd, NULL);
+  gdb::unique_xmalloc_ptr<char> filename = scan_filename (&cmd, NULL);
 
   /* Find the low address.  */
   if (cmd == NULL || *cmd == '\0')
     error (_("Missing start address."));
-  lo_exp = scan_expression_with_cleanup (&cmd, NULL);
+  gdb::unique_xmalloc_ptr<char> lo_exp = scan_expression (&cmd, NULL);
 
   /* Find the second address - rest of line.  */
   if (cmd == NULL || *cmd == '\0')
     error (_("Missing stop address."));
   hi_exp = cmd;
 
-  lo = parse_and_eval_address (lo_exp);
+  lo = parse_and_eval_address (lo_exp.get ());
   hi = parse_and_eval_address (hi_exp);
   if (hi <= lo)
     error (_("Invalid memory address range (start >= end)."));
@@ -223,15 +209,9 @@  dump_memory_to_file (const char *cmd, const char *mode, const char *file_format)
   
   /* Have everything.  Open/write the data.  */
   if (file_format == NULL || strcmp (file_format, "binary") == 0)
-    {
-      dump_binary_file (filename, mode, buf.data (), count);
-    }
+    dump_binary_file (filename.get (), mode, buf.data (), count);
   else
-    {
-      dump_bfd_file (filename, mode, file_format, lo, buf.data (), count);
-    }
-
-  do_cleanups (old_cleanups);
+    dump_bfd_file (filename.get (), mode, file_format, lo, buf.data (), count);
 }
 
 static void
@@ -243,12 +223,10 @@  dump_memory_command (char *cmd, const char *mode)
 static void
 dump_value_to_file (const char *cmd, const char *mode, const char *file_format)
 {
-  struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
   struct value *val;
-  const char *filename;
 
   /* Open the file.  */
-  filename = scan_filename_with_cleanup (&cmd, NULL);
+  gdb::unique_xmalloc_ptr<char> filename = scan_filename (&cmd, NULL);
 
   /* Find the value.  */
   if (cmd == NULL || *cmd == '\0')
@@ -259,10 +237,8 @@  dump_value_to_file (const char *cmd, const char *mode, const char *file_format)
 
   /* Have everything.  Open/write the data.  */
   if (file_format == NULL || strcmp (file_format, "binary") == 0)
-    {
-      dump_binary_file (filename, mode, value_contents (val), 
-			TYPE_LENGTH (value_type (val)));
-    }
+    dump_binary_file (filename.get (), mode, value_contents (val),
+		      TYPE_LENGTH (value_type (val)));
   else
     {
       CORE_ADDR vaddr;
@@ -277,12 +253,10 @@  dump_value_to_file (const char *cmd, const char *mode, const char *file_format)
 	  warning (_("value is not an lval: address assumed to be zero"));
 	}
 
-      dump_bfd_file (filename, mode, file_format, vaddr, 
+      dump_bfd_file (filename.get (), mode, file_format, vaddr,
 		     value_contents (val), 
 		     TYPE_LENGTH (value_type (val)));
     }
-
-  do_cleanups (old_cleanups);
 }
 
 static void
@@ -541,7 +515,6 @@  restore_binary_file (const char *filename, struct callback_data *data)
 static void
 restore_command (char *args_in, int from_tty)
 {
-  char *filename;
   struct callback_data data;
   bfd *ibfd;
   int binary_flag = 0;
@@ -555,7 +528,7 @@  restore_command (char *args_in, int from_tty)
   data.load_end    = 0;
 
   /* Parse the input arguments.  First is filename (required).  */
-  filename = scan_filename_with_cleanup (&args, NULL);
+  gdb::unique_xmalloc_ptr<char> filename = scan_filename (&args, NULL);
   if (args != NULL && *args != '\0')
     {
       static const char binary_string[] = "binary";
@@ -570,13 +543,13 @@  restore_command (char *args_in, int from_tty)
       /* Parse offset (optional).  */
       if (args != NULL && *args != '\0')
 	data.load_offset = binary_flag ?
-	  parse_and_eval_address (scan_expression_with_cleanup (&args, NULL)) :
-	  parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
+	  parse_and_eval_address (scan_expression (&args, NULL).get ()) :
+	  parse_and_eval_long (scan_expression (&args, NULL).get ());
       if (args != NULL && *args != '\0')
 	{
 	  /* Parse start address (optional).  */
 	  data.load_start = 
-	    parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
+	    parse_and_eval_long (scan_expression (&args, NULL).get ());
 	  if (args != NULL && *args != '\0')
 	    {
 	      /* Parse end address (optional).  */
@@ -589,18 +562,18 @@  restore_command (char *args_in, int from_tty)
 
   if (info_verbose)
     printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
-		     filename, (unsigned long) data.load_offset, 
+		     filename.get (), (unsigned long) data.load_offset,
 		     (unsigned long) data.load_start, 
 		     (unsigned long) data.load_end);
 
   if (binary_flag)
     {
-      restore_binary_file (filename, &data);
+      restore_binary_file (filename.get (), &data);
     }
   else
     {
       /* Open the file for loading.  */
-      gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename, NULL));
+      gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename.get (), NULL));
 
       /* Process the sections.  */
       bfd_map_over_sections (ibfd.get (), restore_section_callback, &data);
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index 473e664..41d5fc3 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -624,44 +624,45 @@  compile_object_load (const compile_file_names &file_names,
   unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
   struct compile_module *retval;
   struct type *regs_type, *out_value_type = NULL;
-  char *filename, **matching;
+  char **matching;
   struct objfile *objfile;
   int expect_parameters;
   struct type *expect_return_type;
   struct munmap_list *munmap_list_head = NULL;
 
-  filename = tilde_expand (file_names.object_file ());
-  cleanups = make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> filename
+    (tilde_expand (file_names.object_file ()));
 
-  gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename, gnutarget, -1));
+  gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename.get (), gnutarget, -1));
   if (abfd == NULL)
     error (_("\"%s\": could not open as compiled module: %s"),
-          filename, bfd_errmsg (bfd_get_error ()));
+          filename.get (), bfd_errmsg (bfd_get_error ()));
 
   if (!bfd_check_format_matches (abfd.get (), bfd_object, &matching))
     error (_("\"%s\": not in loadable format: %s"),
-          filename, gdb_bfd_errmsg (bfd_get_error (), matching));
+          filename.get (), gdb_bfd_errmsg (bfd_get_error (), matching));
 
   if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0)
-    error (_("\"%s\": not in object format."), filename);
+    error (_("\"%s\": not in object format."), filename.get ());
 
   setup_sections_data.last_size = 0;
   setup_sections_data.last_section_first = abfd->sections;
   setup_sections_data.last_prot = -1;
   setup_sections_data.last_max_alignment = 1;
   setup_sections_data.munmap_list_headp = &munmap_list_head;
-  make_cleanup (munmap_listp_free_cleanup, &munmap_list_head);
+  cleanups = make_cleanup (munmap_listp_free_cleanup, &munmap_list_head);
   bfd_map_over_sections (abfd.get (), setup_sections, &setup_sections_data);
   setup_sections (abfd.get (), NULL, &setup_sections_data);
 
   storage_needed = bfd_get_symtab_upper_bound (abfd.get ());
   if (storage_needed < 0)
     error (_("Cannot read symbols of compiled module \"%s\": %s"),
-          filename, bfd_errmsg (bfd_get_error ()));
+          filename.get (), bfd_errmsg (bfd_get_error ()));
 
   /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
      "Reading symbols from ..." message for automatically generated file.  */
-  objfile = symbol_file_add_from_bfd (abfd.get (), filename, 0, NULL, 0, NULL);
+  objfile = symbol_file_add_from_bfd (abfd.get (), filename.get (),
+				      0, NULL, 0, NULL);
   cleanups_free_objfile = make_cleanup_free_objfile (objfile);
 
   func_sym = lookup_global_symbol_from_objfile (objfile,
@@ -713,7 +714,7 @@  compile_object_load (const compile_file_names &file_names,
   number_of_symbols = bfd_canonicalize_symtab (abfd.get (), symbol_table);
   if (number_of_symbols < 0)
     error (_("Cannot parse symbols of compiled module \"%s\": %s"),
-          filename, bfd_errmsg (bfd_get_error ()));
+          filename.get (), bfd_errmsg (bfd_get_error ()));
 
   missing_symbols = 0;
   for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
@@ -762,7 +763,7 @@  compile_object_load (const compile_file_names &file_names,
 	default:
 	  warning (_("Could not find symbol \"%s\" "
 		     "for compiled module \"%s\"."),
-		   sym->name, filename);
+		   sym->name, filename.get ());
 	  missing_symbols++;
 	}
     }
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 5dbabc7..ac72268 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -277,7 +277,6 @@  core_open (const char *arg, int from_tty)
   char *temp;
   int scratch_chan;
   int flags;
-  char *filename;
 
   target_preopen (from_tty);
   if (!arg)
@@ -289,31 +288,25 @@  core_open (const char *arg, int from_tty)
 	error (_("No core file specified."));
     }
 
-  filename = tilde_expand (arg);
-  if (!IS_ABSOLUTE_PATH (filename))
-    {
-      temp = concat (current_directory, "/",
-		     filename, (char *) NULL);
-      xfree (filename);
-      filename = temp;
-    }
-
-  old_chain = make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
+  if (!IS_ABSOLUTE_PATH (filename.get ()))
+    filename.reset (concat (current_directory, "/",
+			    filename.get (), (char *) NULL));
 
   flags = O_BINARY | O_LARGEFILE;
   if (write_files)
     flags |= O_RDWR;
   else
     flags |= O_RDONLY;
-  scratch_chan = gdb_open_cloexec (filename, flags, 0);
+  scratch_chan = gdb_open_cloexec (filename.get (), flags, 0);
   if (scratch_chan < 0)
-    perror_with_name (filename);
+    perror_with_name (filename.get ());
 
-  gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget,
+  gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename.get (), gnutarget,
 					   write_files ? FOPEN_RUB : FOPEN_RB,
 					   scratch_chan));
   if (temp_bfd == NULL)
-    perror_with_name (filename);
+    perror_with_name (filename.get ());
 
   if (!bfd_check_format (temp_bfd.get (), bfd_core)
       && !gdb_check_format (temp_bfd.get ()))
@@ -323,13 +316,12 @@  core_open (const char *arg, int from_tty)
          thing, on error it does not free all the storage associated
          with the bfd).  */
       error (_("\"%s\" is not a core dump: %s"),
-	     filename, bfd_errmsg (bfd_get_error ()));
+	     filename.get (), bfd_errmsg (bfd_get_error ()));
     }
 
   /* Looks semi-reasonable.  Toss the old core file and work on the
      new.  */
 
-  do_cleanups (old_chain);
   unpush_target (&core_ops);
   core_bfd = temp_bfd.release ();
   old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index a3762b5..8283545 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1906,7 +1906,6 @@  static void
 maintenance_print_psymbols (char *args, int from_tty)
 {
   struct ui_file *outfile = gdb_stdout;
-  struct cleanup *cleanups;
   char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
   struct objfile *objfile;
   struct partial_symtab *ps;
@@ -1917,7 +1916,6 @@  maintenance_print_psymbols (char *args, int from_tty)
   dont_repeat ();
 
   gdb_argv argv (args);
-  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
@@ -1962,14 +1960,12 @@  maintenance_print_psymbols (char *args, int from_tty)
 
   if (argv != NULL && argv[outfile_idx] != NULL)
     {
-      char *outfile_name;
-
       if (argv[outfile_idx + 1] != NULL)
 	error (_("Junk at end of command"));
-      outfile_name = tilde_expand (argv[outfile_idx]);
-      make_cleanup (xfree, outfile_name);
-      if (!arg_outfile.open (outfile_name, FOPEN_WT))
-	perror_with_name (outfile_name);
+      gdb::unique_xmalloc_ptr<char> outfile_name
+	(tilde_expand (argv[outfile_idx]));
+      if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
+	perror_with_name (outfile_name.get ());
       outfile = &arg_outfile;
     }
 
@@ -2060,8 +2056,6 @@  maintenance_print_psymbols (char *args, int from_tty)
       if (source_arg != NULL)
 	error (_("No partial symtab for source file: %s"), source_arg);
     }
-
-  do_cleanups (cleanups);
 }
 
 /* List all the partial symbol tables whose names match REGEXP (optional).  */
diff --git a/gdb/solib.c b/gdb/solib.c
index 5b538eb..c8fe4d2 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -546,14 +546,10 @@  static int
 solib_map_sections (struct so_list *so)
 {
   const struct target_so_ops *ops = solib_ops (target_gdbarch ());
-  char *filename;
   struct target_section *p;
-  struct cleanup *old_chain;
 
-  filename = tilde_expand (so->so_name);
-  old_chain = make_cleanup (xfree, filename);
-  gdb_bfd_ref_ptr abfd (ops->bfd_open (filename));
-  do_cleanups (old_chain);
+  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so->so_name));
+  gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
 
   if (abfd == NULL)
     return 0;
@@ -1301,28 +1297,24 @@  static void
 reload_shared_libraries_1 (int from_tty)
 {
   struct so_list *so;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
 
   if (print_symbol_loading_p (from_tty, 0, 0))
     printf_unfiltered (_("Loading symbols for shared libraries.\n"));
 
   for (so = so_list_head; so != NULL; so = so->next)
     {
-      char *filename, *found_pathname = NULL;
+      char *found_pathname = NULL;
       int was_loaded = so->symbols_loaded;
       symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;
 
       if (from_tty)
 	add_flags |= SYMFILE_VERBOSE;
 
-      filename = tilde_expand (so->so_original_name);
-      make_cleanup (xfree, filename);
-      gdb_bfd_ref_ptr abfd (solib_bfd_open (filename));
+      gdb::unique_xmalloc_ptr<char> filename
+	(tilde_expand (so->so_original_name));
+      gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
       if (abfd != NULL)
-	{
-	  found_pathname = xstrdup (bfd_get_filename (abfd.get ()));
-	  make_cleanup (xfree, found_pathname);
-	}
+	found_pathname = bfd_get_filename (abfd.get ());
 
       /* If this shared library is no longer associated with its previous
 	 symbol file, close that.  */
@@ -1364,8 +1356,6 @@  reload_shared_libraries_1 (int from_tty)
 	      solib_read_symbols (so, add_flags);
 	}
     }
-
-  do_cleanups (old_chain);
 }
 
 static void
diff --git a/gdb/source.c b/gdb/source.c
index 5473103..769d9ef 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -855,20 +855,18 @@  openp (const char *path, int opts, const char *string,
 	{
 	 /* See whether we need to expand the tilde.  */
 	  int newlen;
-	  char *tilde_expanded;
 
-	  tilde_expanded  = tilde_expand (dir);
+	  gdb::unique_xmalloc_ptr<char> tilde_expanded (tilde_expand (dir));
 
 	  /* First, realloc the filename buffer if too short.  */
-	  len = strlen (tilde_expanded);
+	  len = strlen (tilde_expanded.get ());
 	  newlen = len + strlen (string) + 2;
 	  if (newlen > alloclen)
 	    {
 	      alloclen = newlen;
 	      filename = (char *) alloca (alloclen);
 	    }
-	  strcpy (filename, tilde_expanded);
-	  xfree (tilde_expanded);
+	  strcpy (filename, tilde_expanded.get ());
 	}
       else
 	{
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 67a3976..3e2df9b 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1714,32 +1714,28 @@  symfile_bfd_open (const char *name)
 
   if (!is_target_filename (name))
     {
-      char *expanded_name, *absolute_name;
+      char *absolute_name;
 
-      expanded_name = tilde_expand (name); /* Returns 1st new malloc'd copy.  */
+      gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (name));
 
       /* Look down path for it, allocate 2nd new malloc'd copy.  */
       desc = openp (getenv ("PATH"),
 		    OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
-		    expanded_name, O_RDONLY | O_BINARY, &absolute_name);
+		    expanded_name.get (), O_RDONLY | O_BINARY, &absolute_name);
 #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
       if (desc < 0)
 	{
-	  char *exename = (char *) alloca (strlen (expanded_name) + 5);
+	  char *exename = (char *) alloca (strlen (expanded_name.get ()) + 5);
 
-	  strcat (strcpy (exename, expanded_name), ".exe");
+	  strcat (strcpy (exename, expanded_name.get ()), ".exe");
 	  desc = openp (getenv ("PATH"),
 			OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
 			exename, O_RDONLY | O_BINARY, &absolute_name);
 	}
 #endif
       if (desc < 0)
-	{
-	  make_cleanup (xfree, expanded_name);
-	  perror_with_name (expanded_name);
-	}
+	perror_with_name (expanded_name.get ());
 
-      xfree (expanded_name);
       make_cleanup (xfree, absolute_name);
       name = absolute_name;
     }
@@ -2055,7 +2051,6 @@  static void print_transfer_performance (struct ui_file *stream,
 void
 generic_load (const char *args, int from_tty)
 {
-  char *filename;
   struct cleanup *old_cleanups;
   struct load_section_data cbdata;
   struct load_progress_data total_progress;
@@ -2074,8 +2069,7 @@  generic_load (const char *args, int from_tty)
 
   gdb_argv argv (args);
 
-  filename = tilde_expand (argv[0]);
-  make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));
 
   if (argv[1] != NULL)
     {
@@ -2093,16 +2087,13 @@  generic_load (const char *args, int from_tty)
     }
 
   /* Open the file for loading.  */
-  gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename, gnutarget, -1));
+  gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename.get (), gnutarget, -1));
   if (loadfile_bfd == NULL)
-    {
-      perror_with_name (filename);
-      return;
-    }
+    perror_with_name (filename.get ());
 
   if (!bfd_check_format (loadfile_bfd.get (), bfd_object))
     {
-      error (_("\"%s\" is not an object file: %s"), filename,
+      error (_("\"%s\" is not an object file: %s"), filename.get (),
 	     bfd_errmsg (bfd_get_error ()));
     }
 
@@ -2212,7 +2203,7 @@  static void
 add_symbol_file_command (char *args, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
-  char *filename = NULL;
+  gdb::unique_xmalloc_ptr<char> filename;
   char *arg;
   int section_index = 0;
   int argcnt = 0;
@@ -2254,8 +2245,7 @@  add_symbol_file_command (char *args, int from_tty)
       if (argcnt == 0)
 	{
 	  /* The first argument is the file name.  */
-	  filename = tilde_expand (arg);
-	  make_cleanup (xfree, filename);
+	  filename.reset (tilde_expand (arg));
 	}
       else if (argcnt == 1)
 	{
@@ -2312,7 +2302,8 @@  add_symbol_file_command (char *args, int from_tty)
      loaded.  Abort now if this address hasn't been provided by the
      user.  */
   if (section_index < 1)
-    error (_("The address where %s has been loaded is missing"), filename);
+    error (_("The address where %s has been loaded is missing"),
+	   filename.get ());
 
   /* Print the prompt for the query below.  And save the arguments into
      a sect_addr_info structure to be passed around to other
@@ -2320,7 +2311,8 @@  add_symbol_file_command (char *args, int from_tty)
      statements because hex_string returns a local static
      string.  */
 
-  printf_unfiltered (_("add symbol table from file \"%s\" at\n"), filename);
+  printf_unfiltered (_("add symbol table from file \"%s\" at\n"),
+		     filename.get ());
   section_addrs = alloc_section_addr_info (section_index);
   make_cleanup (xfree, section_addrs);
   for (i = 0; i < section_index; i++)
@@ -2350,7 +2342,7 @@  add_symbol_file_command (char *args, int from_tty)
   if (from_tty && (!query ("%s", "")))
     error (_("Not confirmed."));
 
-  objf = symbol_file_add (filename, add_flags, section_addrs, flags);
+  objf = symbol_file_add (filename.get (), add_flags, section_addrs, flags);
 
   add_target_sections_of_objfile (objf);
 
@@ -2367,7 +2359,6 @@  static void
 remove_symbol_file_command (char *args, int from_tty)
 {
   struct objfile *objf = NULL;
-  struct cleanup *my_cleanups;
   struct program_space *pspace = current_program_space;
 
   dont_repeat ();
@@ -2375,8 +2366,6 @@  remove_symbol_file_command (char *args, int from_tty)
   if (args == NULL)
     error (_("remove-symbol-file: no symbol file provided"));
 
-  my_cleanups = make_cleanup (null_cleanup, NULL);
-
   gdb_argv argv (args);
 
   if (strcmp (argv[0], "-a") == 0)
@@ -2403,20 +2392,18 @@  remove_symbol_file_command (char *args, int from_tty)
   else if (argv[0] != NULL)
     {
       /* Interpret the current argument as a file name.  */
-      char *filename;
 
       if (argv[1] != NULL)
 	error (_("Junk after %s"), argv[0]);
 
-      filename = tilde_expand (argv[0]);
-      make_cleanup (xfree, filename);
+      gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));
 
       ALL_OBJFILES (objf)
 	{
 	  if ((objf->flags & OBJF_USERLOADED) != 0
 	      && (objf->flags & OBJF_SHARED) != 0
 	      && objf->pspace == pspace
-	      && filename_cmp (filename, objfile_name (objf)) == 0)
+	      && filename_cmp (filename.get (), objfile_name (objf)) == 0)
 	    break;
 	}
     }
@@ -2431,8 +2418,6 @@  remove_symbol_file_command (char *args, int from_tty)
 
   free_objfile (objf);
   clear_symtab_users (0);
-
-  do_cleanups (my_cleanups);
 }
 
 /* Re-read symbols if a symbol-file has changed.  */
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index cfdd5d9..c85f0b7 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -408,14 +408,12 @@  static void
 maintenance_print_symbols (char *args, int from_tty)
 {
   struct ui_file *outfile = gdb_stdout;
-  struct cleanup *cleanups;
   char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
   int i, outfile_idx;
 
   dont_repeat ();
 
   gdb_argv argv (args);
-  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
@@ -460,14 +458,12 @@  maintenance_print_symbols (char *args, int from_tty)
 
   if (argv != NULL && argv[outfile_idx] != NULL)
     {
-      char *outfile_name;
-
       if (argv[outfile_idx + 1] != NULL)
 	error (_("Junk at end of command"));
-      outfile_name = tilde_expand (argv[outfile_idx]);
-      make_cleanup (xfree, outfile_name);
-      if (!arg_outfile.open (outfile_name, FOPEN_WT))
-	perror_with_name (outfile_name);
+      gdb::unique_xmalloc_ptr<char> outfile_name
+	(tilde_expand (argv[outfile_idx]));
+      if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
+	perror_with_name (outfile_name.get ());
       outfile = &arg_outfile;
     }
 
@@ -519,8 +515,6 @@  maintenance_print_symbols (char *args, int from_tty)
       if (source_arg != NULL && !found)
 	error (_("No symtab for source file: %s"), source_arg);
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Print symbol ARGS->SYMBOL on ARGS->OUTFILE.  ARGS->DEPTH says how
@@ -709,7 +703,6 @@  static void
 maintenance_print_msymbols (char *args, int from_tty)
 {
   struct ui_file *outfile = gdb_stdout;
-  struct cleanup *cleanups;
   char *objfile_arg = NULL;
   struct objfile *objfile;
   int i, outfile_idx;
@@ -717,7 +710,6 @@  maintenance_print_msymbols (char *args, int from_tty)
   dont_repeat ();
 
   gdb_argv argv (args);
-  cleanups = make_cleanup (null_cleanup, NULL);
 
   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
     {
@@ -747,14 +739,12 @@  maintenance_print_msymbols (char *args, int from_tty)
 
   if (argv != NULL && argv[outfile_idx] != NULL)
     {
-      char *outfile_name;
-
       if (argv[outfile_idx + 1] != NULL)
 	error (_("Junk at end of command"));
-      outfile_name = tilde_expand (argv[outfile_idx]);
-      make_cleanup (xfree, outfile_name);
-      if (!arg_outfile.open (outfile_name, FOPEN_WT))
-	perror_with_name (outfile_name);
+      gdb::unique_xmalloc_ptr<char> outfile_name
+	(tilde_expand (argv[outfile_idx]));
+      if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
+	perror_with_name (outfile_name.get ());
       outfile = &arg_outfile;
     }
 
@@ -765,8 +755,6 @@  maintenance_print_msymbols (char *args, int from_tty)
 	|| compare_filenames_for_search (objfile_name (objfile), objfile_arg))
       dump_msymbols (objfile, outfile);
   }
-
-  do_cleanups (cleanups);
 }
 
 static void
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index fb4283f..37bd96a 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -423,7 +423,6 @@  static void
 tfile_open (const char *arg, int from_tty)
 {
   char *temp;
-  struct cleanup *old_chain;
   int flags;
   int scratch_chan;
   char header[TRACE_HEADER_SIZE];
@@ -433,34 +432,27 @@  tfile_open (const char *arg, int from_tty)
   struct trace_status *ts;
   struct uploaded_tp *uploaded_tps = NULL;
   struct uploaded_tsv *uploaded_tsvs = NULL;
-  char *filename;
 
   target_preopen (from_tty);
   if (!arg)
     error (_("No trace file specified."));
 
-  filename = tilde_expand (arg);
-  if (!IS_ABSOLUTE_PATH(filename))
-    {
-      temp = concat (current_directory, "/", filename, (char *) NULL);
-      xfree (filename);
-      filename = temp;
-    }
-
-  old_chain = make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
+  if (!IS_ABSOLUTE_PATH (filename.get ()))
+    filename.reset (concat (current_directory, "/", filename.get (),
+			    (char *) NULL));
 
   flags = O_BINARY | O_LARGEFILE;
   flags |= O_RDONLY;
-  scratch_chan = gdb_open_cloexec (filename, flags, 0);
+  scratch_chan = gdb_open_cloexec (filename.get (), flags, 0);
   if (scratch_chan < 0)
-    perror_with_name (filename);
+    perror_with_name (filename.get ());
 
   /* Looks semi-reasonable.  Toss the old trace file and work on the new.  */
 
-  discard_cleanups (old_chain);	/* Don't free filename any more.  */
   unpush_target (&tfile_ops);
 
-  trace_filename = xstrdup (filename);
+  trace_filename = filename.release ();
   trace_fd = scratch_chan;
 
   /* Make sure this is clear.  */