This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[type-refcount] [commit] Fix access to already freed `structtype's on [vla]+[python].


commit acd14fd258b498d2faa5dc34751c43da5c8e476f

Found by archer-jankratochvil-vla x archer-tromey-python.

Even if TYPE has no more references still do not delete it as callers may hold
pointers to types dynamically generated by check_typedef where type_incref is
never called.  Always rely on the free_all_types garbage collector.

gdb/
	* gdbtypes.c (type_refc_remove): Remove the refc parameter and its use.
	(type_decref): New assertion on REFC.  Remove deletion of unused types.
	(free_all_types): New comment part when to call this function.
---
 gdb/gdbtypes.c |   34 ++++++++++++----------------------
 1 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index bd77774..45266ba 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3348,16 +3348,14 @@ type_incref (struct type *type)
 }
 
 /* A traverse callback for type_refc_table which removes any entry
-   whose reference count pointer is REFC.  REFC may be NULL to delete all the
-   unused entries - use such cleanup only in the GDB idle state as GDB code
-   does not necessarily reference county TYPEs during its processing.  */
+   whose reference count is zero (unused entry).  */
 
 static int
-type_refc_remove (void **slot, void *refc)
+type_refc_remove (void **slot, void *unused)
 {
   struct type_refc_entry *entry = *slot;
 
-  if (entry->refc == refc || (refc == NULL && *entry->refc == 0))
+  if (*entry->refc == 0)
     {
       delete_type (entry->type);
 
@@ -3368,8 +3366,10 @@ type_refc_remove (void **slot, void *refc)
   return 1;
 }
 
-/* Decrement the reference count for TYPE.  If TYPE has no more
-   references, delete it.  */
+/* Decrement the reference count for TYPE.  Even if TYPE has no more
+   references still do not delete it as callers may hold pointers to types
+   dynamically generated by check_typedef where type_incref is never called.
+   Always rely on the free_all_types garbage collector.  */
 
 void
 type_decref (struct type *type)
@@ -3382,24 +3382,14 @@ type_decref (struct type *type)
   entry.type = type;
   found = htab_find (type_refc_table, &entry);
   gdb_assert (found);
+  gdb_assert (found->refc > 0);
   --*(found->refc);
-  if (*(found->refc) == 0)
-    {
-      void *refc = found->refc;
-
-      /* Clear all table entries referring to this count.  CHECK: Should not be
-         the deletion delayed till free_all_types?  */
-      delete_type_begin ();
-      htab_traverse (type_refc_table, type_refc_remove, refc);
-      delete_type_finish ();
-
-      /* Delete the reference count itself.  */
-      xfree (refc);
-    }
 }
 
-/* Free all the types that have been allocated (except for those released).
-   Called after each command, successful or not.  */
+/* Free all the types that have been allocated and that are not used according
+   to type_refc_entry->refc.  Called after each command, successful or not.
+   Use this cleanup only in the GDB idle state as GDB code does not necessarily
+   use type_incref / type_decref during temporary use of types.  */
 
 void
 free_all_types (void)
-- 
1.6.0.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]