This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
[type-refcount] [commit] Fix access to already freed `structtype's on [vla]+[python].
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: archer at sourceware dot org
- Date: Sat, 28 Feb 2009 20:31:48 +0100
- Subject: [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