This is a multi-part message in MIME format. --------------030305070307090003010905 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit
Gawen ARAB wrote: > Thanks for the report. Unfortunately, it appears the DB was > constructed incorrectly at some time in the past, so even updating > to later revisions of the code won't avoid the crash. It's more > important now to find the sequence of steps that recreates the > invalid DB in the first place, or verify that the same sequence > doesn't crash using the 0.9.15 release candidate. > > > OK. I'll try to reproduce the steps. I reproduced an occurrence of this assert using the attached test program. This particular bug is now fixed in git, but since we never had a test case for your original situation it's still unconfirmed whether this fix addresses your issue. Were you able to do any further testing? -- -- Howard Chu CTO, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/ --------------030305070307090003010905 Content-Type: text/x-csrc; name="its8062.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="its8062.c" /* mtest.c - memory-mapped database tester/toy */ /* * Copyright 2011-2015 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "lmdb.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) /* Write an 8 byte integer in big-endian order */ void L2B(unsigned long l, char *c) { int i; for (i=7; i>=0; i--) { c[i] = l & 0xff; l >>= 8; } } int main(int argc,char * argv[]) { int i = 0, j = 0, rc; MDB_env *env; MDB_dbi dbi; MDB_val headkey1, headkey2, headkey3, TERMINATOR; MDB_val key, data; MDB_txn *txn; MDB_cursor *cursor; int count = 1024; char ck1[24], ck2[24], ck3[24], ckx[32], cterm[511]; char cvar[1024]; E(mdb_env_create(&env)); E(mdb_env_set_mapsize(env, 1024*1024*1024)); E(mdb_env_set_maxdbs(env, 2)); E(mdb_env_open(env, "./testdb", MDB_NOSYNC, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); E(mdb_dbi_open(txn, "test", MDB_CREATE, &dbi)); E(mdb_txn_commit(txn)); /* set up 3 partitions of data */ headkey1.mv_size = 24; headkey1.mv_data = ck1; headkey2.mv_size = 24; headkey2.mv_data = ck2; headkey3.mv_size = 24; headkey3.mv_data = ck3; /* and a final record */ TERMINATOR.mv_size = sizeof(cterm); TERMINATOR.mv_data = cterm; memset(cterm, 255, sizeof(cterm)); memset(ck1, 0, 24); memset(ck2, 0, 24); memset(ck3, 0, 24); memset(ckx, 0, 24); /* Assign the 3 partition keys */ L2B(1, ck1); L2B(-1, ck2); L2B(0, ck3); E(mdb_txn_begin(env, NULL, 0, &txn)); /* Terminator data is a single NUL byte */ data.mv_size = 1; data.mv_data = cvar; cvar[0] = 0; E(mdb_put(txn, dbi, &TERMINATOR, &data, 0)); /* Partition data is 24 NUL bytes */ memset(cvar, 0, 24); data.mv_size = 24; E(mdb_put(txn, dbi, &headkey1, &data, 0)); E(mdb_put(txn, dbi, &headkey2, &data, 0)); E(mdb_put(txn, dbi, &headkey3, &data, 0)); /* Main data is 35 NUL bytes, keys are 32 bytes */ memset(cvar, 0, 35); data.mv_size = 35; key.mv_data = ckx; key.mv_size = 32; for (i=1; i<=count; i++) { L2B(i, ckx+24); memcpy(ckx, headkey1.mv_data, 24); E(mdb_put(txn, dbi, &key, &data, 0)); memcpy(ckx, headkey2.mv_data, 24); E(mdb_put(txn, dbi, &key, &data, 0)); memcpy(ckx, headkey3.mv_data, 24); E(mdb_put(txn, dbi, &key, &data, 0)); } /* Delete from 1st partition */ E(mdb_cursor_open(txn, dbi, &cursor)); E(mdb_cursor_get(cursor, &headkey1, &data, MDB_SET)); for (i=0; i<count; i++) { E(mdb_cursor_del(cursor, 0)); E(mdb_cursor_get(cursor, &key, &data, MDB_NEXT)); } mdb_cursor_close(cursor); /* Delete from 2nd partition - assert happens here */ E(mdb_cursor_open(txn, dbi, &cursor)); E(mdb_cursor_get(cursor, &headkey2, &data, MDB_SET)); for (i=0; i<count; i++) { E(mdb_cursor_del(cursor, 0)); E(mdb_cursor_get(cursor, &key, &data, MDB_NEXT)); } mdb_cursor_close(cursor); /* Delete from 3rd partition - not reached */ E(mdb_cursor_open(txn, dbi, &cursor)); E(mdb_cursor_get(cursor, &headkey3, &data, MDB_SET)); for (i=0; i<count; i++) { E(mdb_cursor_del(cursor, 0)); E(mdb_cursor_get(cursor, &key, &data, MDB_NEXT)); } mdb_cursor_close(cursor); E(mdb_txn_commit(txn)); mdb_dbi_close(env, dbi); mdb_env_close(env); return 0; } --------------030305070307090003010905--
