Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mdb_del : Invalid argument for simple deletion #24

Open
DrissiReda opened this issue Mar 18, 2019 · 9 comments
Open

mdb_del : Invalid argument for simple deletion #24

DrissiReda opened this issue Mar 18, 2019 · 9 comments

Comments

@DrissiReda
Copy link

I tried to simply delete an entry, and can't really know if I'm wrong or if this is a bug, the only documentation I could find was the api reference, if anyone has better material I'd be glad to take it.

#include <cstdio>
#include <cstdlib>
#include <lmdb++.h>
using namespace lmdb;
int main() {
  auto env = lmdb::env::create();
  env.set_mapsize(1UL * 1024UL * 1024UL); 
  env.open("./example.mdb", 0, 0664);

  auto wtxn = lmdb::txn::begin(env);
  auto dbi = lmdb::dbi::open(wtxn, nullptr);
  dbi.put(wtxn, "key_entry", "value_entry");
  wtxn.commit();
  dbi.del(wtxn, "key_entry");

  return EXIT_SUCCESS;
}

This yields the following error :

terminate called after throwing an instance of 'lmdb::runtime_error'
  what():  mdb_del: Invalid argument
@hoytech
Copy link

hoytech commented Mar 18, 2019

You are calling dbi.del(wtxn, ...) after you are calling wtxn.commit(). Committing (or aborting) a transaction invalidates it. You can't then use it for subsequent operations. Either do the delete in the same transaction, or open a new transaction.

BTW: This repo is not really maintained anymore. I'll try to answer questions as best as possible here, but I have forked it for C++17 and will try to maintain that fork: https://github.com/hoytech/lmdbxx

@DrissiReda
Copy link
Author

is your fork compatible with C++11?

@hoytech
Copy link

hoytech commented Mar 18, 2019

My fork requires a C++17 compiler since it uses std::string_view. However, C++11 code will I believe compile fine with a C++17 compiler.

@DrissiReda
Copy link
Author

Thanks, I'll look into it

@hoytech
Copy link

hoytech commented Mar 18, 2019

Oh, and you asked about docs. You sort of have to use the LMDB C API docs: http://www.lmdb.tech/doc/

For examples of the C++ interface, you can checkout my test code, it has more working C++ examples than does this repo: https://github.com/hoytech/lmdbxx/blob/master/check.cc

@DrissiReda
Copy link
Author

Currently I'm limited to C++11, what you told me worked, but I have issues with dbi.get now. If it doesn't find the entry, everything works normally, if it does find the entry, I have a segmentation fault on the call dbi.get

#include <cstdio>
#include <cstdlib>
#include <lmdb++.h>
using namespace lmdb;
int main() {
  auto env = lmdb::env::create();
  env.set_mapsize(1UL * 1024UL * 1024UL * 1024UL); /* 1 GiB */
  env.open("./example.mdb", 0, 0664);
  {
    auto wtxn = lmdb::txn::begin(env);
    auto dbi = lmdb::dbi::open(wtxn, nullptr);
    dbi.put(wtxn, "email", "hello");
    wtxn.commit();
  }
  {
    auto rtxn = lmdb::txn::begin(env, nullptr, MDB_RDONLY);
    auto mydb = lmdb::dbi::open(rtxn, nullptr);
    std::string v;
    mydb.get(rtxn, "email", v);
    //std::printf("we found '%s'", v.c_str());
  }

  return EXIT_SUCCESS;
}

A snippet from valgrind:

==80114== Process terminating with default action of signal 11 (SIGSEGV)
==80114==  Access not within mapped region at address 0x106F6C6C6560
==80114==    at 0x510A02C: std::string::assign(std::string const&) (in /usr/lib64/libstdc++.so.6.0.19)
==80114==    by 0x4020A3: bool lmdb::dbi::get<std::string>(MDB_txn*, char const*, std::string&) const (in /home/reda/lmdbxx-master/test)
==80114==    by 0x40155E: main (in /home/reda/lmdbxx-master/test)
==80114==  If you believe this happened as a result of a stack
==80114==  overflow in your program's main thread (unlikely but
==80114==  possible), you can try to increase the size of the
==80114==  main thread stack using the --main-stacksize= flag.
==80114==  The main thread stack size used in this run was 8388608.

A warning printed prior to the error that might be relevant:

==80114== Warning: set address range perms: large range [0x39602000, 0x79602000) (defined)
==80114== Invalid read of size 4
==80114==    at 0x510A02C: std::string::assign(std::string const&) (in /usr/lib64/libstdc++.so.6.0.19)
==80114==    by 0x4020A3: bool lmdb::dbi::get<std::string>(MDB_txn*, char const*, std::string&) const (in /home/reda/lmdbxx-master/test)
==80114==    by 0x40155E: main (in /home/reda/lmdbxx-master/test)
==80114==  Address 0x106f6c6c6560 is not stack'd, malloc'd or (recently) free'd

@hoytech
Copy link

hoytech commented Mar 18, 2019

You are using the templated get method with std::string. Don't do that: #1

Use lmdb::val instead. You can then construct an std::string from that by copying the value from the DB.

@DrissiReda
Copy link
Author

DrissiReda commented Mar 18, 2019

using lmdb::val gives an ambiguity error:

EDIT: nevermind, using an lmdb::val object for the key instead of a const char* fixed it.

@hoytech
Copy link

hoytech commented Mar 18, 2019

You have to use it for the key too. Passing a const char* works in my fork because it implicitly creates a string_view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants