From 176afc3c8b97b66a724636b0f5ad75a8587e2729 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Fri, 25 Apr 2025 18:09:02 +0100 Subject: [PATCH] libctf: open: fix closing of children with imported parents 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 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index b58c0c4030c..251940833e3 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -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); -- 2.47.2