gdb: Make ldirname return a std::string
authorPedro Alves <palves@redhat.com>
Mon, 27 Mar 2017 10:56:28 +0000 (11:56 +0100)
committerPedro Alves <palves@redhat.com>
Mon, 27 Mar 2017 10:56:28 +0000 (11:56 +0100)
Eliminates several uses of cleanups.

Tested on x86_64 Fedora 23 with Python 2 and 3.

gdb/ChangeLog
2017-03-27  Pedro Alves  <palves@redhat.com>

* dwarf2read.c (struct file_and_directory): New.
(dwarf2_get_dwz_file): Adjust to use std::string.
(dw2_get_file_names_reader): Adjust to use file_and_directory.
(find_file_and_directory): Adjust to return a file_and_directory
object.
(read_file_scope): Adjust to use file_and_directory.  Remove
make_cleanup/do_cleanups calls.
(open_and_init_dwp_file): Adjust to use std::string.  Remove
make_cleanup/do_cleanups calls.
* python/python.c (do_start_initialization): Adjust to ldirname
returning a std::string.
* utils.c (ldirname): Now returns a std::string.
* utils.h (ldirname): Change return type to std::string.
* xml-syscall.c (xml_init_syscalls_info): Adjust to ldirname
returning a std::string.
* xml-tdesc.c (file_read_description_xml): Likewise.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/python/python.c
gdb/utils.c
gdb/utils.h
gdb/xml-syscall.c
gdb/xml-tdesc.c

index a687fae5a4109c9dd7ca401b1a0bcc8ea1d195df..82213e87d9ebc963d0ebd8d4b316dd27d81241d0 100644 (file)
@@ -1,3 +1,22 @@
+2017-03-27  Pedro Alves  <palves@redhat.com>
+
+       * dwarf2read.c (struct file_and_directory): New.
+       (dwarf2_get_dwz_file): Adjust to use std::string.
+       (dw2_get_file_names_reader): Adjust to use file_and_directory.
+       (find_file_and_directory): Adjust to return a file_and_directory
+       object.
+       (read_file_scope): Adjust to use file_and_directory.  Remove
+       make_cleanup/do_cleanups calls.
+       (open_and_init_dwp_file): Adjust to use std::string.  Remove
+       make_cleanup/do_cleanups calls.
+       * python/python.c (do_start_initialization): Adjust to ldirname
+       returning a std::string.
+       * utils.c (ldirname): Now returns a std::string.
+       * utils.h (ldirname): Change return type to std::string.
+       * xml-syscall.c (xml_init_syscalls_info): Adjust to ldirname
+       returning a std::string.
+       * xml-tdesc.c (file_read_description_xml): Likewise.
+
 2017-03-24  Alan Hayward  <alan.hayward@arm.com>
 
        * regcache.c (regcache_debug_print_register): New function.
index 519550b4d1e651adf01ec3ba976292c7859687d6..f3429502d5cfa1fe9ed772445852ee364679cc0f 100644 (file)
@@ -1885,9 +1885,27 @@ static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
 
 static void process_queue (void);
 
-static void find_file_and_directory (struct die_info *die,
-                                    struct dwarf2_cu *cu,
-                                    const char **name, const char **comp_dir);
+/* The return type of find_file_and_directory.  Note, the enclosed
+   string pointers are only valid while this object is valid.  */
+
+struct file_and_directory
+{
+  /* The filename.  This is never NULL.  */
+  const char *name;
+
+  /* The compilation directory.  NULL if not known.  If we needed to
+     compute a new string, this points to COMP_DIR_STORAGE, otherwise,
+     points directly to the DW_AT_comp_dir string attribute owned by
+     the obstack that owns the DIE.  */
+  const char *comp_dir;
+
+  /* If we needed to build a new string for comp_dir, this is what
+     owns the storage.  */
+  std::string comp_dir_storage;
+};
+
+static file_and_directory find_file_and_directory (struct die_info *die,
+                                                  struct dwarf2_cu *cu);
 
 static char *file_full_name (int file, struct line_header *lh,
                             const char *comp_dir);
@@ -2552,18 +2570,15 @@ dwarf2_get_dwz_file (void)
   buildid_len = (size_t) buildid_len_arg;
 
   filename = (const char *) data;
+
+  std::string abs_storage;
   if (!IS_ABSOLUTE_PATH (filename))
     {
       char *abs = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile));
-      char *rel;
 
       make_cleanup (xfree, abs);
-      abs = ldirname (abs);
-      make_cleanup (xfree, abs);
-
-      rel = concat (abs, SLASH_STRING, filename, (char *) NULL);
-      make_cleanup (xfree, rel);
-      filename = rel;
+      abs_storage = ldirname (abs) + SLASH_STRING + filename;
+      filename = abs_storage.c_str ();
     }
 
   /* First try the file name given in the section.  If that doesn't
@@ -3332,7 +3347,6 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
   struct line_header *lh;
   struct attribute *attr;
   int i;
-  const char *name, *comp_dir;
   void **slot;
   struct quick_file_names *qfn;
   unsigned int line_offset;
@@ -3385,13 +3399,13 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
   gdb_assert (slot != NULL);
   *slot = qfn;
 
-  find_file_and_directory (comp_unit_die, cu, &name, &comp_dir);
+  file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
 
   qfn->num_file_names = lh->num_file_names;
   qfn->file_names =
     XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->num_file_names);
   for (i = 0; i < lh->num_file_names; ++i)
-    qfn->file_names[i] = file_full_name (i + 1, lh, comp_dir);
+    qfn->file_names[i] = file_full_name (i + 1, lh, fnd.comp_dir);
   qfn->real_names = NULL;
 
   free_line_header (lh);
@@ -9122,37 +9136,38 @@ producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
   return cu->producer_is_gcc_lt_4_3;
 }
 
-static void
-find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
-                        const char **name, const char **comp_dir)
+static file_and_directory
+find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
 {
+  file_and_directory res;
+
   /* Find the filename.  Do not use dwarf2_name here, since the filename
      is not a source language identifier.  */
-  *name = dwarf2_string_attr (die, DW_AT_name, cu);
-  *comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
+  res.name = dwarf2_string_attr (die, DW_AT_name, cu);
+  res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
 
-  if (*comp_dir == NULL
-      && producer_is_gcc_lt_4_3 (cu) && *name != NULL
-      && IS_ABSOLUTE_PATH (*name))
+  if (res.comp_dir == NULL
+      && producer_is_gcc_lt_4_3 (cu) && res.name != NULL
+      && IS_ABSOLUTE_PATH (res.name))
     {
-      char *d = ldirname (*name);
-
-      *comp_dir = d;
-      if (d != NULL)
-       make_cleanup (xfree, d);
+      res.comp_dir_storage = ldirname (res.name);
+      if (!res.comp_dir_storage.empty ())
+       res.comp_dir = res.comp_dir_storage.c_str ();
     }
-  if (*comp_dir != NULL)
+  if (res.comp_dir != NULL)
     {
       /* Irix 6.2 native cc prepends <machine>.: to the compilation
         directory, get rid of it.  */
-      const char *cp = strchr (*comp_dir, ':');
+      const char *cp = strchr (res.comp_dir, ':');
 
-      if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/')
-       *comp_dir = cp + 1;
+      if (cp && cp != res.comp_dir && cp[-1] == '.' && cp[1] == '/')
+       res.comp_dir = cp + 1;
     }
 
-  if (*name == NULL)
-    *name = "<unknown>";
+  if (res.name == NULL)
+    res.name = "<unknown>";
+
+  return res;
 }
 
 /* Handle DW_AT_stmt_list for a compilation unit.
@@ -9262,12 +9277,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
-  const char *name = NULL;
-  const char *comp_dir = NULL;
   struct die_info *child_die;
   CORE_ADDR baseaddr;
 
@@ -9281,7 +9293,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
     lowpc = highpc;
   lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
 
-  find_file_and_directory (die, cu, &name, &comp_dir);
+  file_and_directory fnd = find_file_and_directory (die, cu);
 
   prepare_one_comp_unit (cu, die, cu->language);
 
@@ -9295,12 +9307,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
     set_cu_language (DW_LANG_Go, cu);
 
-  dwarf2_start_symtab (cu, name, comp_dir, lowpc);
+  dwarf2_start_symtab (cu, fnd.name, fnd.comp_dir, lowpc);
 
   /* Decode line number information if present.  We do this before
      processing child DIEs, so that the line header table is available
      for DW_AT_decl_file.  */
-  handle_DW_AT_stmt_list (die, cu, comp_dir, lowpc);
+  handle_DW_AT_stmt_list (die, cu, fnd.comp_dir, lowpc);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -9338,8 +9350,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
          dwarf_decode_macros (cu, macro_offset, 0);
        }
     }
-
-  do_cleanups (back_to);
 }
 
 /* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
@@ -10893,49 +10903,44 @@ open_and_init_dwp_file (void)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwp_file *dwp_file;
-  char *dwp_name;
-  struct cleanup *cleanups = make_cleanup (null_cleanup, 0);
 
   /* Try to find first .dwp for the binary file before any symbolic links
      resolving.  */
 
   /* If the objfile is a debug file, find the name of the real binary
      file and get the name of dwp file from there.  */
+  std::string dwp_name;
   if (objfile->separate_debug_objfile_backlink != NULL)
     {
       struct objfile *backlink = objfile->separate_debug_objfile_backlink;
       const char *backlink_basename = lbasename (backlink->original_name);
-      char *debug_dirname = ldirname (objfile->original_name);
 
-      make_cleanup (xfree, debug_dirname);
-      dwp_name = xstrprintf ("%s%s%s.dwp", debug_dirname,
-                            SLASH_STRING, backlink_basename);
+      dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
     }
   else
-    dwp_name = xstrprintf ("%s.dwp", objfile->original_name);
-  make_cleanup (xfree, dwp_name);
+    dwp_name = objfile->original_name;
+
+  dwp_name += ".dwp";
 
-  gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name));
+  gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name.c_str ()));
   if (dbfd == NULL
       && strcmp (objfile->original_name, objfile_name (objfile)) != 0)
     {
       /* Try to find .dwp for the binary file after gdb_realpath resolving.  */
-      dwp_name = xstrprintf ("%s.dwp", objfile_name (objfile));
-      make_cleanup (xfree, dwp_name);
-      dbfd = open_dwp_file (dwp_name);
+      dwp_name = objfile_name (objfile);
+      dwp_name += ".dwp";
+      dbfd = open_dwp_file (dwp_name.c_str ());
     }
 
   if (dbfd == NULL)
     {
       if (dwarf_read_debug)
-       fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
-      do_cleanups (cleanups);
+       fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name.c_str ());
       return NULL;
     }
   dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
   dwp_file->name = bfd_get_filename (dbfd.get ());
   dwp_file->dbfd = dbfd.release ();
-  do_cleanups (cleanups);
 
   /* +1: section 0 is unused */
   dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1;
@@ -10959,7 +10964,7 @@ open_and_init_dwp_file (void)
       error (_("Dwarf Error: DWP file CU version %s doesn't match"
               " TU version %s [in DWP file %s]"),
             pulongest (dwp_file->cus->version),
-            pulongest (dwp_file->tus->version), dwp_name);
+            pulongest (dwp_file->tus->version), dwp_name.c_str ());
     }
   dwp_file->version = dwp_file->cus->version;
 
index d21e023591400092d78f798f099eb08126544803..a7aff5336c92eada42e898928bfa5ea2558031ac 100644 (file)
@@ -1550,10 +1550,8 @@ do_start_initialization ()
      /foo/bin/python
      /foo/lib/pythonX.Y/...
      This must be done before calling Py_Initialize.  */
-  char *libdir = ldirname (python_libdir);
-  progname = concat (libdir, SLASH_STRING, "bin",
+  progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin",
                     SLASH_STRING, "python", (char *) NULL);
-  xfree (libdir);
 #ifdef IS_PY3K
   oldloc = xstrdup (setlocale (LC_ALL, NULL));
   setlocale (LC_ALL, "");
index 27021a1d458329c4552aef3b1a7951198d8c27e1..39798cc47ede0c26d949c26e08b0f41373e49a69 100644 (file)
@@ -2943,20 +2943,19 @@ dummy_obstack_deallocate (void *object, void *data)
 /* Simple, portable version of dirname that does not modify its
    argument.  */
 
-char *
+std::string
 ldirname (const char *filename)
 {
+  std::string dirname;
   const char *base = lbasename (filename);
-  char *dirname;
 
   while (base > filename && IS_DIR_SEPARATOR (base[-1]))
     --base;
 
   if (base == filename)
-    return NULL;
+    return dirname;
 
-  dirname = (char *) xmalloc (base - filename + 2);
-  memcpy (dirname, filename, base - filename);
+  dirname = std::string (filename, base - filename);
 
   /* On DOS based file systems, convert "d:foo" to "d:.", so that we
      create "d:./bar" later instead of the (different) "d:/bar".  */
@@ -2964,7 +2963,6 @@ ldirname (const char *filename)
       && !IS_DIR_SEPARATOR (filename[0]))
     dirname[base++ - filename] = '.';
 
-  dirname[base - filename] = '\0';
   return dirname;
 }
 
index f138702b3a430a5c5cc305ebf5d68b0e86ecc0ac..fb75f2e97c7e47a9f9c711a1ccb0ca7107727edb 100644 (file)
@@ -135,7 +135,7 @@ extern int gdb_filename_fnmatch (const char *pattern, const char *string,
 extern void substitute_path_component (char **stringp, const char *from,
                                       const char *to);
 
-char *ldirname (const char *filename);
+std::string ldirname (const char *filename);
 
 extern int count_path_elements (const char *path);
 
index 1e42b8d8a6ff4ddfaaa9771f755b6527ad2141ca..a43641893a60488a5ee47f70bd537cbbc6d2a108 100644 (file)
@@ -363,7 +363,6 @@ static struct syscalls_info *
 xml_init_syscalls_info (const char *filename)
 {
   char *full_file;
-  char *dirname;
   struct syscalls_info *syscalls_info;
   struct cleanup *back_to;
 
@@ -373,12 +372,9 @@ xml_init_syscalls_info (const char *filename)
 
   back_to = make_cleanup (xfree, full_file);
 
-  dirname = ldirname (filename);
-  if (dirname != NULL)
-    make_cleanup (xfree, dirname);
-
   syscalls_info = syscall_parse_xml (full_file,
-                                    xml_fetch_content_from_file, dirname);
+                                    xml_fetch_content_from_file,
+                                    (void *) ldirname (filename).c_str ());
   do_cleanups (back_to);
 
   return syscalls_info;
index 16776594bfea440ab856a89a4ede6f5c7c936f78..effe65281d81d3fd989855068734fb43b76fe22d 100644 (file)
@@ -694,7 +694,6 @@ file_read_description_xml (const char *filename)
   struct target_desc *tdesc;
   char *tdesc_str;
   struct cleanup *back_to;
-  char *dirname;
 
   tdesc_str = xml_fetch_content_from_file (filename, NULL);
   if (tdesc_str == NULL)
@@ -705,11 +704,8 @@ file_read_description_xml (const char *filename)
 
   back_to = make_cleanup (xfree, tdesc_str);
 
-  dirname = ldirname (filename);
-  if (dirname != NULL)
-    make_cleanup (xfree, dirname);
-
-  tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
+  tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file,
+                          (void *) ldirname (filename).c_str ());
   do_cleanups (back_to);
 
   return tdesc;