Full_Name: Nic Watson Version: LMDB v 0.9.21 OS: Ubuntu 17.04 URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (108.56.136.246)
I'm getting a seg fault in using LMDB on a database opened with MDB_DUPSORT.
Here's a minimal set of operations that will cause the problem:
#include <stdio.h> #include "lmdb.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
void cause_crash() { MDB_env *env; MDB_txn *txn; MDB_dbi dbi; int rc; int line_fail = 0; MDB_val key = {.mv_size = 1, .mv_data = "a"}; MDB_val vals[] = { { .mv_size = 8, .mv_data = "\x00\x00\x00\x00\x00\x00\x00\x00" }, { .mv_size = 1, .mv_data = "\x05" }, { .mv_size = 1, .mv_data = "\t" }, { .mv_size = 1, .mv_data = "\r" }, { .mv_size = 1, .mv_data = "\x11" }, { .mv_size = 1, .mv_data = "\x15" }, { .mv_size = 1, .mv_data = "\x19" }, { .mv_size = 1, .mv_data = "\x1d" }, { .mv_size = 1, .mv_data = "!" }, { .mv_size = 1, .mv_data = "%" }, { .mv_size = 1, .mv_data = ")" }, { .mv_size = 1, .mv_data = "-" }, { .mv_size = 1, .mv_data = "1" }, { .mv_size = 1, .mv_data = "5" }, };
rc = mdb_env_create(&env); if (rc) { line_fail = __LINE__; goto fail; }
rc = mdb_env_set_maxdbs(env, 2); if (rc) { line_fail = __LINE__; goto fail; }
rc = mdb_env_open(env, "foo.lmdb", 0, 0777); if (rc) { line_fail = __LINE__; goto fail; }
rc = mdb_txn_begin(env, NULL, 0, &txn); if (rc) { line_fail = __LINE__; goto fail; }
rc = mdb_dbi_open(txn, "another_db", MDB_CREATE | MDB_DUPSORT, &dbi); if (rc) { line_fail = __LINE__; goto fail; }
rc = mdb_txn_commit(txn); if (rc) { line_fail = __LINE__; goto fail; }
rc = mdb_txn_begin(env, NULL, 0, &txn); if (rc) { line_fail = __LINE__; goto fail; }
for (int i = 0; i < ARRAY_SIZE(vals); i++) { rc = mdb_put(txn, dbi, &key, &vals[i], 0); if (rc) { line_fail = __LINE__; goto fail; } }
rc = mdb_txn_commit(txn); if (rc) { line_fail = __LINE__; goto fail; }
mdb_dbi_close(env, dbi); mdb_env_close(env);
return;
fail: printf("Failed with error %d on line %d\n", rc, line_fail); }
int main(int argc, char **argv) { printf("Running %s\n", MDB_VERSION_STRING); cause_crash(); printf("Didn't crash!\n"); return 0; }
Here's a simple sh make script:
LMDB_DIR=~/src/lmdb/libraries/liblmdb gcc-6 -O3 -ggdb -std=c11 -Wall -I $LMDB_DIR lmdb_crash2.c $LMDB_DIR/{mdb.c,midl.c} -lpthread -o mdb_c_exe mkdir -p foo.lmdb
Here's a basic stack trace: Program received signal SIGSEGV, Segmentation fault. 0x000055555555ee7c in mdb_cursor_put (mc=mc@entry=0x7fffffffcfa0, key=key@entry=0x7fffffffd380, data=data@entry=0x7fffffffd460, flags=flags@entry=0) at /home/nic/src/lmdb/libraries/liblmdb/mdb.c:6792 6792 mp->mp_ptrs[i] = fp->mp_ptrs[i] + offset; (gdb) bt #0 0x000055555555ee7c in mdb_cursor_put (mc=mc@entry=0x7fffffffcfa0, key=key@entry=0x7fffffffd380, data=data@entry=0x7fffffffd460, flags=flags@entry=0) at /home/nic/src/lmdb/libraries/liblmdb/mdb.c:6792 #1 0x00005555555635d0 in mdb_cursor_put (flags=0, data=0x7fffffffd460, key=0x7fffffffd380, mc=0x7fffffffcfa0) at /home/nic/src/lmdb/libraries/liblmdb/mdb.c:8984 #2 mdb_put (txn=0x55555576e8d0,
It will *not* crash under debug. In fact, -O3 -fvect-cost-model=cheap will *not* crash. This makes some sense since it is crashing on an SSE instruction.
I tried gcc versions (Ubuntu 7.2.0-8ubuntu3.2) and (Ubuntu 6.4.0-8ubuntu1) with the same result. I also tried with the mdb.master branch (0.9.70) with the same result.
I'm not convinced this a fault in your code. It may be a gcc bug.