# New Ticket Created by Sean O'Rourke # Please include the string: [netlabs #610] # in the subject line of all future correspondence about this issue. # <URL: http://bugs6.perl.org/rt2/Ticket/Display.html?id=610 >
I believe there is a bug in how the perlhash pmc adjusts its buckets after reallocation. When the allocator hands it a new piece of memory that is aligned differently with respect to sizeof(HASHBUCKET) boundaries (32 bytes on linux-ppc), it will adjust pointers by a multiple of sizeof(HASHBUCKET), causing wierd segfaults. I believe the included patch fixes it. I didn't look for similar issues elsewhere, but the tests all seem to run now. /s *** hash.c.~1.3.~ Sun May 19 18:28:32 2002 --- hash.c Tue May 21 18:59:33 2002 *************** *** 87,101 **** /* fprintf(stderr, "Moving hash %p buckets from %p -> %p\n", */ /* hash, hash->former_base, current_base); */ ! adjust = current_base - hash->former_base; /* Fix up the free list */ ! if (hash->free_list) hash->free_list += adjust; /* Fix up the hashtable */ table = (HASHBUCKET**) hash->buffer.bufstart; for (i = 0; i < hash->num_buckets; i++) { ! if (table[i]) table[i] += adjust; } /* Fix up the buckets themselves. All buckets in the pool are --- 87,103 ---- /* fprintf(stderr, "Moving hash %p buckets from %p -> %p\n", */ /* hash, hash->former_base, current_base); */ ! adjust = (char*)current_base - (char*)hash->former_base; /* Fix up the free list */ ! if (hash->free_list) ! hash->free_list = (HASHBUCKET*)((char*)hash->free_list + adjust); /* Fix up the hashtable */ table = (HASHBUCKET**) hash->buffer.bufstart; for (i = 0; i < hash->num_buckets; i++) { ! if (table[i]) ! table[i] = (HASHBUCKET*)((char*)table[i] + adjust); } /* Fix up the buckets themselves. All buckets in the pool are *************** *** 104,110 **** * chains. */ table_size = hash->bucket_pool->buflen / sizeof(HASHBUCKET); for (i = 0; i < table_size; i++) { ! if (current_base[i].next) current_base[i].next += adjust; } hash->former_base = current_base; --- 106,114 ---- * chains. */ table_size = hash->bucket_pool->buflen / sizeof(HASHBUCKET); for (i = 0; i < table_size; i++) { ! if (current_base[i].next) ! current_base[i].next = (HASHBUCKET*)((char*)current_base[i].next ! + adjust); } hash->former_base = current_base; __________________________________________________ Do You Yahoo!? LAUNCH - Your Yahoo! Music Experience http://launch.yahoo.com