[Bug libobjc/11904] New: Problem in sarray_free() function.
sergant at orcsoftware dot spb dot ru
gcc-bugzilla@gcc.gnu.org
Wed Aug 13 09:18:00 GMT 2003
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11904
Summary: Problem in sarray_free() function.
Product: gcc
Version: tree-ssa
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libobjc
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: sergant at orcsoftware dot spb dot ru
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-mingw32
GCC host triplet: i686-pc-mingw32
GCC target triplet: i686-pc-mingw32
sarray_lazy_copy() function creates an array with reference to the original
array and pointers to the original array's buckets. sarray_free() function
looks like:
void
sarray_free(struct sarray* array) {
... some code ...
if((array->is_copy_of) && ((array->is_copy_of->ref_count - 1) == 0))
sarray_free(array->is_copy_of);
/* Free all entries that do not point to empty_bucket */
for(counter = 0; counter <= old_max_index; counter++ ) {
#ifdef OBJC_SPARSE3
struct sindex* idx = old_indices[counter];
if((idx != array->empty_index) &&
(idx->version.version == array->version.version)) {
int c2;
for(c2=0; c2<INDEX_SIZE; c2++) {
struct sbucket* bkt = idx->buckets[c2];
if((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
}
sarray_free_garbage(idx);
nindices -= 1;
}
#else /* OBJC_SPARSE2 */
struct sbucket* bkt = array->buckets[counter];
if ((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
#endif
}
... some code ...
}
In case, when array is a lazy copy of some other array it calls sarray_free()
for the oroginal array, and then deallocates it's own created buckets. Array
can have some pointers to the original array's buckets that are already
deallocated, and thus sometimes we have access to the freed memory in block of
code:
struct sbucket* bkt = array->buckets[counter];
if ((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
at line '(bkt->version.version == array->version.version)' (memory pointed
by 'bkt' can be already freed).
The possible solution of this problem is to move deallocation of (array-
>is_copy_of) array to the end of function sarray_free().
More information about the Gcc-bugs
mailing list