CoreyKaylor / Lightning.NET

.NET library for LMDB key-value store
Other
398 stars 82 forks source link

lmdb c code core dumps #98

Closed mr-miles closed 4 years ago

mr-miles commented 7 years ago

Hi,

Sorry for posting so many issues here! I'm not trying to be a nuisance, actually lightningDb/lmdb is turning out to be a massive success for us - thanks!

Debugging an odd behaviour we encountered in a new app, we found we could reliably make the lmdb c code core dump (windows/.net) and crash the runtime with an uncatchable exception (heap corruption). It looks like doing a cursor put with CursorPutOptions.Current when the cursor is past the last record bypasses any checks that the cursor is correctly positioned.

Here's the repro. I'm putting it here because I'm not sure whether its fixed in newer binaries - my c is not good enough to tell for definite.

        var path = @"C:\temp\tester\";
        using (var env = new LightningEnvironment(path))
        {
            env.Open();
            using (var txn = env.BeginTransaction())
            using (var db = txn.OpenDatabase(configuration: new DatabaseConfiguration {Flags = DatabaseOpenFlags.Create}))
            {
                // write a key
                using (var cur = txn.CreateCursor(db))
                {
                    var k = new byte[] {32};
                    cur.Put(k, k, CursorPutOptions.None);
                }

                // write a value
                using (var cur = txn.CreateCursor(db))
                {
                    // position ourselves past the last item in the tree
                    var k = new byte[] { 200 };
                    var found = cur.MoveTo(k);
                    // cur.Current.Key is null as expected
                    cur.Put(k, k, CursorPutOptions.Current);
                }
            }
        }
        Directory.Delete(path, true);
CoreyKaylor commented 4 years ago

Given that no key was found on MoveTo, there is no guarantee on where the cursor would put the value. It isn't seeking to the next index beyond what you're trying to find if that's the assumption.

If I've misunderstood something, feel free to reopen.