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

Bug in last LMDB GitHub commit (Windows + VL32)



Pretty excited about the 32bit support!  I was just kicking the tires on it today and I realize this is still a work in progress, but I wanted to report a possible bug with VL32/Windows.

 

When I open a database with MDB_RDONLY and seek a cursor to MDB_LAST, I get a system error code of 0xc000004e (STATUS_SECTION_PROTECTION) from NtMapViewOfSection.  This is presumably because of the MEM_RESERVE_FLAG is present on the open of the db when MDB_RDONLY is used.

 

After patching up the NtMapViewOfSection, I get a 0xc000001f(STATUS_INVALID_VIEW_SIZE) from NtMapViewOfSection.  I believe this happens because it is requesting a view that goes beyond the size of the db.  A quick adjustment on the “len” being requested seems to have “fixed” it.

 

I have included a diff patch below.  I realize this is a naïve hack, but hoped it could be useful in reproducing and fixing.

 

-Jer

 

diff --git a/src/lmdb/mdb.c b/src/lmdb/mdb.c

index 297d3e3..d594a6f 100644

--- a/src/lmdb/mdb.c

+++ b/src/lmdb/mdb.c

@@ -5655,7 +5655,7 @@ mdb_rpage_get(MDB_txn *txn, pgno_t pg0, MDB_page **ret)

#define MAP(rc,env,addr,len,off)           \

             addr = NULL; \

             rc = NtMapViewOfSection(env->me_fmh, GetCurrentProcess(), &addr, 0, \

-                           len, &off, &len, ViewUnmap, MEM_RESERVE, PAGE_READONLY)

+                           len, &off, &len, ViewUnmap, ((env->me_flags & MDB_RDONLY) == 0) ? MEM_RESERVE : 0, PAGE_READONLY)

#else

             off_t off;

             size_t len;

@@ -5835,6 +5835,14 @@ retry:

                                          }

                            }

                            SET_OFF(off, pgno * env->me_psize);

+

+#ifdef MDB_VL32

+        if(off.QuadPart + len > env->me_mapsize)

+        {

+            len = env->me_mapsize - off.QuadPart;

+        }

+#endif

+

                            MAP(rc, env, id3.mptr, len, off);

                            if (rc) {

fail: