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

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

GDBM 1.8.0 bug report


From: Peter Wullinger
Subject: GDBM 1.8.0 bug report
Date: Mon, 26 Feb 2001 16:04:06 +0100
User-agent: Mutt/1.2.5i

/*
Problem in:
- GNU DBM Version: 1.8.0, May 19, 1999.

Environments tested:
- FreeBSD 5.0-CURRENT i386 (gcc version 2.95.2 19991024 (release))

The bug ist not reproducable on
- Solaris/SunOS 5.7 i386 (gcc version egcs-2.91.66 19990314)

gdbm_get will fail with 
        - gdbm_errno = GDBM_ITEM_NOT_FOUND
                or 
        - "fatal_error: read_error"

fatal errors occur, when using larger
record sizes for values. ( ESIZE >= ~ 128)
The number of simultaniously stored values
must also be large (NROUNDS >= ~ 10000)

Note, that commenting out the gdbm_delete()
causes the problem to magically disappear.

Code fragment that produces the error:

*/
/* --------------------- cut here ----------------------------- */
#include <stdio.h>
#include <gdbm.h>

#define ESIZE   128
#define NROUNDS 10000

int
main(void)
{
        int             i, ik;
        char            iv[ESIZE];
        datum           k, v;
        GDBM_FILE       db;

        /* create database */
        db = gdbm_open("/tmp/test.gdbm", 0, GDBM_NEWDB, 0644, NULL);

        ik = 0;
restart:
        ik++;
        i = ik;

        fprintf(stderr, "\nputting from %i:", ik);
        for (; ik % NROUNDS; ik++) {
                /* write anything into data record */
                memset((void *)iv, i, ESIZE);

                /* setup key and value */
                k.dsize = sizeof(int);
                k.dptr = (void *)&ik;
                v.dsize = ESIZE;
                v.dptr = (void *)iv;

                /* store */
                if (gdbm_store(db, k, v, GDBM_INSERT) != 0) {
                        fprintf(stderr, "gdbm_store: error: %i\n", gdbm_errno);
                        exit(1);
                }

                /* print a nice status report */
                if (! (ik % 1000))
                        fprintf(stderr, ">");
        }

        fprintf(stderr, "\ngetting from %i:", i);
        for (; i % NROUNDS; i++) {
                
                /* key setup */
                k.dsize = sizeof(int);
                k.dptr = (void *)&i;

                /* get */
                v = gdbm_fetch(db, k);
                if (v.dptr == NULL) {
                        fprintf(stderr, "gdbm_fetch: error: %i\n", gdbm_errno);
                        exit(1);
                }
                free(v.dptr);

                /* delete entry */
                if (gdbm_delete(db, k) != 0) {
                        fprintf(stderr, "gdbm_del: error\n");
                        exit(1);
                }

                /* print a nice status report */
                if (! (i % 1000))
                        fprintf(stderr, "<");
        }

        /**
         * go back, looping infinitely
         * BEWARE: this possibly does not
         *      do, what it should, when the    
         *      key wraps back to 0.  
         **/
        goto restart; 

        return 0;
}
/* --------------------- cut here ----------------------------- */
/*

The intended purpose of this one is
the implementation of a disked based
fifo queue using incremental keys.


I have tracked down the problem to
an invalid bucket address being passed
to _gdbm_get_bucket in bucket.c. 
In the case of the fatal error, the seek
offset is about 2**63 and causes the lseek to
fail with errno == EFBIG;
I have not currently found out, where the
real reason for this problem is, perhaps this
just happens on my machine.

Peter Wullinger
<address@hidden> <address@hidden>
*/



reply via email to

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