"Michel J Lambert" <[EMAIL PROTECTED]> wrote: > Attached is a .pasm file which causes some string data to be written into > the middle of the string_pool->pool_buffer list of entries, such that when > it tries to dereference foo in new_pmc_header, it's pointing to garbage > memory. 0x20202020 for me, which is four spaces. Changing the save/restore > of spaces in the pasm file to use periods causes the pointer to be > 0x2e2e2e2e. I tried for a bit on this, but couldn't really track it down > any more than that. Hopefully someone else can figure it out.
Two problems found so far: 1) mem_realloc passes the incorrect size to Parrot_allocate (this causes the specific error mentioned above) 2) add_header_to_free calls mem_realloc calls Parrot_allocate calls go_collect which moves the free header pool The first is a simple fix; the second needs either suppression of collection during the procedure, or not using mem_realloc. The patch below puts the reallocation code into add_header_to_free and add_pmc_to_free, this means that, in the scenario described, the free pool will be moved by the garbage collector, and then immediately moved again. Since the free pools are not compressed by go_collect, perhaps they should be allocated independently and not copied around all the time?? After fixing the above, the test program still abends, this time with "subend somehow is less than substart" - I have not yet followed up on this. -- Peter Gibbs EmKel Systems Index: memory.c =================================================================== RCS file: /home/perlcvs/parrot/memory.c,v retrieving revision 1.29 diff -u -r1.29 memory.c --- memory.c 18 Mar 2002 16:42:06 -0000 1.29 +++ memory.c 29 Mar 2002 17:41:17 -0000 @@ -145,7 +145,7 @@ { size_t copysize = (fromsize > tosize ? tosize : fromsize); void *mem; - mem = Parrot_allocate(interpreter, copysize); + mem = Parrot_allocate(interpreter, tosize); if (!mem) { return NULL; } Index: resources.c =================================================================== RCS file: /home/perlcvs/parrot/resources.c,v retrieving revision 1.35 diff -u -r1.35 resources.c --- resources.c 26 Mar 2002 16:33:01 -0000 1.35 +++ resources.c 29 Mar 2002 17:42:15 -0000 @@ -18,22 +18,26 @@ static void add_header_to_free(struct Parrot_Interp *interpreter, struct free_pool *pool, void *to_add); -/* Add a string header to the free string header pool */ +/* Add a PMC header to the free pool */ static void add_pmc_to_free(struct Parrot_Interp *interpreter, struct free_pool *pool, void *to_add) { PMC **temp_ptr; /* First, check and see if there's enough space in the free pool. If - we're within the size of a STRING pointer, we make it bigger */ + we're within the size of a pointer, we make it bigger */ if (pool->entries_in_pool * sizeof(PMC *) >= pool->pool_buffer.buflen - sizeof(PMC *)) { /* If not, make the free pool bigger. We enlarge it by 20% */ - pool->pool_buffer.bufstart = mem_realloc(interpreter, - pool->pool_buffer.bufstart, - pool->pool_buffer.buflen, - (UINTVAL)(pool->pool_buffer.buflen * 1.2)); - pool->pool_buffer.buflen = (UINTVAL)(pool->pool_buffer.buflen * 1.2); - + /* don't use mem_realloc, because garbage collection may occur */ + size_t new_size = pool->pool_buffer.buflen * 1.2; + void *new_ptr = Parrot_allocate(interpreter, new_size); + if (!new_ptr) { + internal_exception(ALLOCATION_ERROR, + "No room to expand free PMC pool"); + } + memcpy(new_ptr, pool->pool_buffer.bufstart, pool->pool_buffer.buflen); + pool->pool_buffer.bufstart = new_ptr; + pool->pool_buffer.buflen = new_size; } /* Okay, so there's space. Add the header on */ @@ -269,12 +273,16 @@ if (pool->entries_in_pool * sizeof(STRING *) >= pool->pool_buffer.buflen - sizeof(STRING *)) { /* If not, make the free pool bigger. We enlarge it by 20% */ - pool->pool_buffer.bufstart = mem_realloc(interpreter, - pool->pool_buffer.bufstart, - pool->pool_buffer.buflen, - (UINTVAL)(pool->pool_buffer.buflen * 1.2)); - pool->pool_buffer.buflen = (UINTVAL)(pool->pool_buffer.buflen * 1.2); - + /* don't use mem_realloc, because garbage collection may occur */ + size_t new_size = pool->pool_buffer.buflen * 1.2; + void *new_ptr = Parrot_allocate(interpreter, new_size); + if (!new_ptr) { + internal_exception(ALLOCATION_ERROR, + "No room to expand free buffer header pool"); + } + memcpy(new_ptr, pool->pool_buffer.bufstart, pool->pool_buffer.buflen); + pool->pool_buffer.bufstart = new_ptr; + pool->pool_buffer.buflen = new_size; } /* Okay, so there's space. Add the header on */