[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#7899) Segfault after transaction comitted

Full_Name: CJS
Version: 0.9.14
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (

In the code below if you comment out the second mdb_txn_begin as below then the
mdb_get will segfault. I finally figured out I need to open a new transaction,
but it may have been more appropriate to return an invalid parameter error then
to segfault.

#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)),

int main() {
  int rc;
  MDB_env *env;
  MDB_txn *txn;
  MDB_dbi dbi;
  MDB_val key, data;
  unsigned long kval = 0xdeadbeef;
  unsigned long dval = 0xbeefdead;

  E(mdb_env_set_mapsize(env, 10485760));
  E(mdb_env_set_maxdbs(env, 4));
  E(mdb_env_open(env, "./lmdbtestdb", MDB_NOSYNC, 0664));
  E(mdb_txn_begin(env, NULL, 0, &txn));
  E(mdb_open(txn, NULL, 0, &dbi));

  key.mv_size = sizeof(kval);
  key.mv_data = &kval;
  data.mv_size = sizeof(dval);
  data.mv_data = &dval;

  printf("kval=0x%016lx, dval=0x%016lx\n", kval, dval);

  RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE));

  //E(mdb_txn_begin(env, NULL, 0, &txn));

  rc = mdb_get(txn, dbi, &key, &data);
  printf("rc=%i (%s)\n", rc, mdb_strerror(rc));

  printf("Result should be 0xbeefdead: 0x%016lx (%lu)\n", *(unsigned long
*)data.mv_data, data.mv_size) ;

  mdb_close(env, dbi);