changed notes changed state Open to Test moved from Incoming to Software Bugs
Full_Name: Dmitri Shubin Version: LMDB 0.9.11 (2727e97) OS: Linux (CentOS 6) URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (80.239.140.98) Hi! I got a crash inside LMDB in mdb_cursor_put() functions when I trying to modify the record under cursor. Simple test: $ cat test-mdb_current.c #include <stdio.h> #include <stdlib.h> #include "lmdb.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) #define DBDIR "./testdb" int main() { int rc; MDB_env *env; MDB_dbi dbi; MDB_txn *txn; MDB_val key, data; MDB_cursor *cursor; int key_v = 17; char data_v[] = "0123456789"; E(system("rm -rf " DBDIR " && mkdir " DBDIR)); E(mdb_env_create(&env)); E(mdb_env_open(env, DBDIR, 0, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); E(mdb_dbi_open(txn, NULL, 0, &dbi)); /* put some data */ key.mv_data = &key_v; key.mv_size = sizeof(key_v); data.mv_data = data_v; data.mv_size = sizeof(data_v); E(mdb_put(txn, dbi, &key, &data, 0)); E(mdb_txn_commit(txn)); /* replace using cursor */ E(mdb_txn_begin(env, NULL, 0, &txn)); E(mdb_cursor_open(txn, dbi, &cursor)); E(mdb_cursor_get(cursor, &key, &data, MDB_SET)); data.mv_data = data_v; data.mv_size = sizeof(data_v) - 1; E(mdb_cursor_put(cursor, &key, &data, MDB_CURRENT)); mdb_cursor_close(cursor); E(mdb_txn_commit(txn)); mdb_dbi_close(env, dbi); mdb_env_close(env); return 0; } $ gcc -g test-mdb_current.c -llmdb -L. -Wl,-rpath,. $ ./a.out Segmentation fault (core dumped) $ gdb a.out ... Program terminated with signal 11, Segmentation fault. #0 0x00007fefaba9895c in mdb_leaf_size (env=0xbd8010, key=0x0, data=0x7fff59e6a830) at mdb.c:6430 6430 sz = LEAFSIZE(key, data); (gdb) bt #0 0x00007fefaba9895c in mdb_leaf_size (env=0xbd8010, key=0x0, data=0x7fff59e6a830) at mdb.c:6430 #1 0x00007fefaba97c53 in mdb_cursor_put (mc=0xbda2f0, key=0x0, data=0x7fff59e6a830, flags=64) at mdb.c:6178 #2 0x0000000000400ee0 in main () at test-mdb_current.c:51 (gdb) l 6425 static size_t 6426 mdb_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data) 6427 { 6428 size_t sz; 6429 6430 sz = LEAFSIZE(key, data); 6431 if (sz > env->me_nodemax) { 6432 /* put on overflow page */ 6433 sz -= data->mv_size - sizeof(pgno_t); 6434 } (gdb) p key $1 = (MDB_val *) 0x0 If I remove MDB_CURRENT flag from mdb_cursor_put() call it works fine. Thanks!
Doc bug, fixed recently: MDB_CURRENT must not change the data size. Also with DUPSORT the data item must sort in the same place as the previous one, that needs to be documented too.
h.b.furuseth@usit.uio.no wrote: > Doc bug, fixed recently: MDB_CURRENT must not change the data size. Wrong. This is a regression due to ITS#7793. That commit has now been reverted. > Also with DUPSORT the data item must sort in the same place as the > previous one, that needs to be documented too. I'll add this note to the doc. -- -- Howard Chu CTO, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
Works after reverting commit (checked f537429) Thanks!
fixed in mdb.master
changed state Test to Release
changed state Release to Closed