]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: open: fix closing of children with imported parents
authorNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:09:02 +0000 (18:09 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:09:02 +0000 (18:09 +0100)
Closing a parent dict for the last time erases all its types and strings,
which makes type and string lookups in any surviving children impossible
from then on.  Since children hold a reference to their parent, this can
only happen in ctf_dict_close of the last child, after the parent has
been closed by the caller as well.  Since DTD deletion now involves
doing type and string lookups in order to clean out the name tables,
close the parent only after the child DTDs have been deleted.

libctf/ctf-open.c

index b58c0c4030c7b36125e9d5457919642dee9611a3..251940833e3502211c5480b7b44743d5851eda39 100644 (file)
@@ -2353,16 +2353,22 @@ ctf_dict_close (ctf_dict_t *fp)
     return;
 
   fp->ctf_refcnt--;
-  if (fp->ctf_parent && !fp->ctf_parent_unreffed)
-    ctf_dict_close (fp->ctf_parent);
   free (fp->ctf_dyn_cu_name);
   free (fp->ctf_dyn_parent_name);
 
+  /* DTD deletion must happen before the parent is deleted, since deleting the
+     parent erases all its types and strings and makes type and string lookups
+     impossible from then on.  */
+
   for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
     {
       ntd = ctf_list_next (dtd);
       ctf_dtd_delete (fp, dtd);
     }
+
+  if (fp->ctf_parent && !fp->ctf_parent_unreffed)
+    ctf_dict_close (fp->ctf_parent);
+
   ctf_dynhash_destroy (fp->ctf_dthash);
 
   ctf_dynset_destroy (fp->ctf_conflicting_enums);