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!