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

(ITS#8347) lmdb VL32 sometimes not unmapping pages

Full_Name: Jeremiah Morrill
Version: lmdb 0.9.70
OS: Windows
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (

I changed the value of MDB_ERPAGE_SIZE to 256(16384/64) to try and tweak high
virtual-memory usage in 32bit.  I believe this exposed a bug not hit in my
testing.  Sometimes mmap'd sections(usually one or two) were not being munmapped
when the environment was closed.  This was only evident after checking the
process with the Windows utility VMMap.

I observed that when this happened, in mdb_env_close0, the dangling mmap'd
sections were always at env->me_rpages[(MDB_ERPAGE_SIZE - 1) / 2], which in the
case of MDB_ERPAGE_SIZE of 256, would be at index 127.

This seemed like a possible off-by-one error.  Below is a diff that seems to fix
the issue, but I do not stand by its correctness.

--- a/src/libraries/lmdb/mdb.c
+++ b/src/libraeses/lmdb/mdb.c
@@ -1404,7 +1404,7 @@ struct MDB_env {
 #ifdef MDB_VL32
 	MDB_ID3L	me_rpages;	/**< like #mt_rpages, but global to env */
 	pthread_mutex_t	me_rpmutex;	/**< control access to #me_rpages */
-#define MDB_ERPAGE_SIZE	16384
+#define MDB_ERPAGE_SIZE	(16384/64)
 	unsigned int me_rpcheck;
@@ -5851,7 +5851,7 @@ retry:
 		if (el[0].mid >= MDB_ERPAGE_MAX - env->me_rpcheck) {
 			/* purge unref'd pages */
 			unsigned i, y = 0;D%D
-			for (i=1; i<el[0].mid; i++) {
+			for (i=1; i<=el[0].mid; i++) {
 				if (!el[i].mref) {
 					if (!y) y = i;
 					munmap(el[i].mptr, env->me_psize * el[i].mcnt);