bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gdbm-1.8.0 fatal bug


From: Jason Downs
Subject: Re: gdbm-1.8.0 fatal bug
Date: Tue, 23 Apr 2002 11:30:08 -0700

In message <address@hidden>,
        Shilad Sen writes:
>Hello,
>
>I think I've located a reproduceable gdbm bug under linux.  It happens when a
>specific set of items are inserted into a database from scratch.  I get a
>gdbm fatal read error.  From cursory glancing over the source it looks to me
>like gdbm is seeking to the end of the file and then getting a short read
>while looking for an empty "bucket."
>
>I've attached a tar file with an example program and text file of keys and
>value lengths to insert.  Please read the README for specific instructions.
>
>A couple of notes:
>
>1. This ONLY happens on 64 bit builds of this (i.e. -D_FILE_OFFSET_BITS=64).
>2. This has been verified on redhat 6.2, 7.1 and 7.2 systems.
>
>Please let me know if this also fails for you,
>
>Shilad

It's not quite the same symptom, but try this diff and see if it fixes
your problem.

One silly question to ask, though... configure was run with CFLAGS containing
-DFILE_OFFSET_BITS=64, and not just added to the Makefile after the fact,
right?

*** falloc.c.1.8        Tue Feb 27 19:58:45 2001
--- falloc.c    Tue Feb 27 22:52:33 2001
***************
*** 180,185 ****
--- 180,192 ----
    avail_block *new_blk;
    int index;
  
+   if (dbf->header->avail.count == dbf->header->avail.size)
+     {
+       /* We're kind of stuck here, so we re-split the header in order to
+          avoid crashing.  Sigh. */
+       push_avail_block(dbf);
+     }
+ 
    /* Set up variables. */
    new_el.av_adr = dbf->header->avail.next_block;
    new_el.av_size = ( ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
***************
*** 196,207 ****
    if (num_bytes != new_el.av_size) _gdbm_fatal (dbf, "read error");
  
    /* Add the elements from the new block to the header. */
!   for (index = 0; index < new_blk->count; index++)
      {
!       /* With luck, this will merge a lot of blocks! */
!       _gdbm_put_av_elem(new_blk->av_table[index],
!                       dbf->header->avail.av_table,
!                       &dbf->header->avail.count, dbf->coalesce_blocks);
      }
  
    /* Fix next_block, as well. */
--- 203,226 ----
    if (num_bytes != new_el.av_size) _gdbm_fatal (dbf, "read error");
  
    /* Add the elements from the new block to the header. */
!   index = 0;
!   while (index < new_blk->count)
      {
!       while(index < new_blk->count
!             && dbf->header->avail.count < dbf->header->avail.size)
!       {
!          /* With luck, this will merge a lot of blocks! */
!          _gdbm_put_av_elem(new_blk->av_table[index],
!                            dbf->header->avail.av_table,
!                            &dbf->header->avail.count, TRUE);
!          index++;
!       }
!       if (dbf->header->avail.count == dbf->header->avail.size)
!         {
!           /* We're kind of stuck here, so we re-split the header in order to
!              avoid crashing.  Sigh. */
!           push_avail_block(dbf);
!       }
      }
  
    /* Fix next_block, as well. */
***************
*** 210,218 ****
    /* We changed the header. */
    dbf->header_changed = TRUE;
  
!   /* Free the previous avail block. */
    _gdbm_put_av_elem (new_el, dbf->header->avail.av_table,
!                    &dbf->header->avail.count, dbf->coalesce_blocks);
    free (new_blk);
  }
  
--- 229,245 ----
    /* We changed the header. */
    dbf->header_changed = TRUE;
  
!   /* Free the previous avail block.   It is possible that the header table
!      is now FULL, which will cause us to overflow it! */
!   if (dbf->header->avail.count == dbf->header->avail.size)
!     {
!       /* We're kind of stuck here, so we re-split the header in order to
!          avoid crashing.  Sigh. */
!       push_avail_block(dbf);
!     }
! 
    _gdbm_put_av_elem (new_el, dbf->header->avail.av_table,
!                    &dbf->header->avail.count, TRUE);
    free (new_blk);
  }
  
***************
*** 336,342 ****
  
    /* Is it too small to deal with? */
    if (new_el.av_size <= IGNORE_SIZE)
!     return FALSE; 
  
    if (can_merge == TRUE)
      {
--- 363,369 ----
  
    /* Is it too small to deal with? */
    if (new_el.av_size <= IGNORE_SIZE)
!     return FALSE;
  
    if (can_merge == TRUE)
      {


--
Jason Downs
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]