drycpp / lmdbxx

C++11 wrapper for the LMDB embedded B+ tree database library.
http://lmdbxx.sourceforge.net
The Unlicense
269 stars 89 forks source link

Cursor double free on write tx #22

Open ZRobison opened 6 years ago

ZRobison commented 6 years ago

Not really sure if this is an issue as I don't think there is any fix for this given the available lmdb library, but I think it is worth noting on github wiki.

As per the lmdb documents for commiting a tx "Earlier documentation incorrectly said all cursors would be freed. Only write-transactions free cursors.".

So when a wite tx is committed AND a cursor object live, the underlying MDB_cursor* is freed during the commit, then freed when the cursor object is destroyed resulting in memory violation. As such the ordering of committing and destroying (or closing) below will crash.

wtxn.commit(); cursor.close();

I do not think there is a way for a cursor to know if the tx has been committed, so there seems to be no trivial fix if one at all.

An easy solution from a users perspective is just to make sure you actively close all cursors of a write tx before before committing. Its pretty simple but it took me a while to figure out where the memory violation was coming from. Perhaps this could be added somewhere to your wiki to warn users of this.

cursor.close(); wtxn.commit();

hoytech commented 5 years ago

Thanks for the very detailed description. I added a section describing this to the docs for my fork of this project:

https://github.com/hoytech/lmdbxx#cursor-double-free-issue