This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC 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]

[Bug libobjc/11904] New: Problem in sarray_free() function.


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().


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