[Q] Assertion failure on Linux/Alpha

Jason Baker kaffe@rufus.w3.org
11 Oct 2000 10:25:56 -0600


Patrick Tullmann <tullmann@cs.utah.edu> writes:

> Kaffe's GC uses the data portion of a gc_unit to store the "next"
> pointer in a free block.  Thus, if the block isn't really free, the
> "next" pointer will overlap with the first word of data in the data
> block.  Or, in your case, I'm guessing that the realloc copies the
> data from the old block into the new block, which is still on the
> freelist.  The data just happens to be all zeros, so it sets
> next to NULL.

Actually, kaffe uses the prev link of the gc_unit as the next *.
You're actually seeing the next* of the following object get trashed:
gcRealloc copies an extra sizeof(gc_unit) bytes after the original
object.  As long as pointers are 4 bytes, the newly allocated object
has room for this junk.  

I just checked the following in.  Does it solve your problem?

Jason

Index: gc-incremental.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/mem/gc-incremental.c,v
retrieving revision 1.59
diff -c -r1.59 gc-incremental.c
*** gc-incremental.c	2000/09/09 21:52:01	1.59
--- gc-incremental.c	2000/10/11 16:17:17
***************
*** 1009,1015 ****
  	unit = UTOUNIT(mem);
  	info = GCMEM2BLOCK(unit);
  	idx = GCMEM2IDX(info, unit);
! 	osize = GCBLOCKSIZE(info);
  
  	/* Can only handled fixed objects at the moment */
  	assert(GC_GET_COLOUR(info, idx) == GC_COLOUR_FIXED);
--- 1009,1015 ----
  	unit = UTOUNIT(mem);
  	info = GCMEM2BLOCK(unit);
  	idx = GCMEM2IDX(info, unit);
! 	osize = GCBLOCKSIZE(info) - sizeof(gc_unit);
  
  	/* Can only handled fixed objects at the moment */
  	assert(GC_GET_COLOUR(info, idx) == GC_COLOUR_FIXED);
***************
*** 1017,1023 ****
  	unlockStaticMutex(&gc_lock);
  
  	/* If we'll fit into the current space, just send it back */
! 	if (osize >= size + sizeof(gc_unit)) {
  		return (mem);
  	}
  
--- 1017,1023 ----
  	unlockStaticMutex(&gc_lock);
  
  	/* If we'll fit into the current space, just send it back */
! 	if (osize >= size) {
  		return (mem);
  	}