Skip to content

mdb_del : Invalid argument for simple deletion #24

Open

Description

@DrissiReda

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

Activity

  1. hoytech commented on Mar 18, 2019

    @hoytech

    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

  2. DrissiReda commented on Mar 18, 2019

    @DrissiReda
    Author

    is your fork compatible with C++11?

  3. hoytech commented on Mar 18, 2019

    @hoytech

    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.

  4. DrissiReda commented on Mar 18, 2019

    @DrissiReda
    Author

    Thanks, I'll look into it

  5. hoytech commented on Mar 18, 2019

    @hoytech

    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

  6. DrissiReda commented on Mar 18, 2019

    @DrissiReda
    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
    
  7. hoytech commented on Mar 18, 2019

    @hoytech

    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.

  8. DrissiReda commented on Mar 18, 2019

    @DrissiReda
    Author

    using lmdb::val gives an ambiguity error:

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

  9. hoytech commented on Mar 18, 2019

    @hoytech

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions