[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#8819) LMDB seg fault with MDB_DUPSORT on -O3
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.