[Top][All Lists]
[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