# 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

Reply via email to