mirror of
				https://github.com/isar/libmdbx.git
				synced 2025-10-31 15:38:57 +08:00 
			
		
		
		
	lmdb: refines Valgrind usage.
Change-Id: I5f30a609b9053bbf8a693b7ca64dc57dc176f6e9
This commit is contained in:
		
							
								
								
									
										110
									
								
								mdb.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								mdb.c
									
									
									
									
									
								
							| @@ -271,18 +271,19 @@ union semun { | |||||||
| #endif /* !_WIN32 */ | #endif /* !_WIN32 */ | ||||||
|  |  | ||||||
| #ifdef USE_VALGRIND | #ifdef USE_VALGRIND | ||||||
| #include <valgrind/memcheck.h> | #	include <valgrind/memcheck.h> | ||||||
| #define VGMEMP_CREATE(h,r,z)    VALGRIND_CREATE_MEMPOOL(h,r,z) |  | ||||||
| #define VGMEMP_ALLOC(h,a,s) VALGRIND_MEMPOOL_ALLOC(h,a,s) |  | ||||||
| #define VGMEMP_FREE(h,a) VALGRIND_MEMPOOL_FREE(h,a) |  | ||||||
| #define VGMEMP_DESTROY(h)	VALGRIND_DESTROY_MEMPOOL(h) |  | ||||||
| #define VGMEMP_DEFINED(a,s)	VALGRIND_MAKE_MEM_DEFINED(a,s) |  | ||||||
| #else | #else | ||||||
| #define VGMEMP_CREATE(h,r,z) | #	define VALGRIND_CREATE_MEMPOOL(h,r,z) | ||||||
| #define VGMEMP_ALLOC(h,a,s) | #	define VALGRIND_DESTROY_MEMPOOL(h) | ||||||
| #define VGMEMP_FREE(h,a) | #	define VALGRIND_MEMPOOL_TRIM(h,a,s) | ||||||
| #define VGMEMP_DESTROY(h) | #	define VALGRIND_MEMPOOL_ALLOC(h,a,s) | ||||||
| #define VGMEMP_DEFINED(a,s) | #	define VALGRIND_MEMPOOL_FREE(h,a) | ||||||
|  | #	define VALGRIND_MEMPOOL_CHANGE(h,a,b,s) | ||||||
|  | #	define VALGRIND_MAKE_MEM_NOACCESS(a,s) | ||||||
|  | #	define VALGRIND_MAKE_MEM_DEFINED(a,s) | ||||||
|  | #	define VALGRIND_MAKE_MEM_UNDEFINED(a,s) | ||||||
|  | #	define VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(a,s) | ||||||
|  | #	define VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(a,s) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef BYTE_ORDER | #ifndef BYTE_ORDER | ||||||
| @@ -1380,6 +1381,9 @@ struct MDB_env { | |||||||
| 	size_t		me_sync_size;	/**< Tracking file size at last sync to decide when fsync() is needed */ | 	size_t		me_sync_size;	/**< Tracking file size at last sync to decide when fsync() is needed */ | ||||||
| #endif /* FDATASYNC_MAYBE_BROKEN */ | #endif /* FDATASYNC_MAYBE_BROKEN */ | ||||||
| 	MDB_oom_func	*me_oom_func; /**< Callback for kicking laggard readers */ | 	MDB_oom_func	*me_oom_func; /**< Callback for kicking laggard readers */ | ||||||
|  | #ifdef USE_VALGRIND | ||||||
|  | 	int me_valgrind_handle; | ||||||
|  | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
| 	/** Nested transaction */ | 	/** Nested transaction */ | ||||||
| @@ -1794,36 +1798,40 @@ static MDB_page * | |||||||
| mdb_page_malloc(MDB_txn *txn, unsigned num) | mdb_page_malloc(MDB_txn *txn, unsigned num) | ||||||
| { | { | ||||||
| 	MDB_env *env = txn->mt_env; | 	MDB_env *env = txn->mt_env; | ||||||
| 	MDB_page *ret = env->me_dpages; | 	size_t size = env->me_psize; | ||||||
| 	size_t psize = env->me_psize, sz = psize, off; | 	MDB_page *np = env->me_dpages; | ||||||
| 	/* For ! #MDB_NOMEMINIT, psize counts how much to init. | 	if (num == 1 && np) { | ||||||
| 	 * For a single page alloc, we init everything after the page header. | 		VALGRIND_MEMPOOL_ALLOC(env, np, size); | ||||||
|  | 		VALGRIND_MAKE_MEM_DEFINED(&np->mp_next, sizeof(np->mp_next)); | ||||||
|  | 		env->me_dpages = np->mp_next; | ||||||
|  | 	} else { | ||||||
|  | 		size *= num; | ||||||
|  | 		np = malloc(size); | ||||||
|  | 		if (! np) { | ||||||
|  | 			txn->mt_flags |= MDB_TXN_ERROR; | ||||||
|  | 			return np; | ||||||
|  | 		} | ||||||
|  | 		VALGRIND_MEMPOOL_ALLOC(env, np, size); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | #ifdef LDAP_MEMORY_DEBUG | ||||||
|  | 	memset(np, 42, size); | ||||||
|  | #else | ||||||
|  | 	if ((env->me_flags & MDB_NOMEMINIT) == 0) { | ||||||
|  | 		/* For a single page alloc, we init everything after the page header. | ||||||
| 		 * For multi-page, we init the final page; if the caller needed that | 		 * For multi-page, we init the final page; if the caller needed that | ||||||
| 		 * many pages they will be filling in at least up to the last page. | 		 * many pages they will be filling in at least up to the last page. | ||||||
| 		 */ | 		 */ | ||||||
| 	if (num == 1) { | 		size_t skip = PAGEHDRSZ; | ||||||
| 		if (ret) { | 		if (num > 1) | ||||||
| 			VGMEMP_ALLOC(env, ret, sz); | 			skip += (num - 1) * env->me_psize; | ||||||
| 			VGMEMP_DEFINED(ret, sizeof(ret->mp_next)); | 		memset((char *) np + skip, 0, size - skip); | ||||||
| 			env->me_dpages = ret->mp_next; |  | ||||||
| 			return ret; |  | ||||||
| 	} | 	} | ||||||
| 		psize -= off = PAGEHDRSZ; | #endif | ||||||
| 	} else { | 	VALGRIND_MAKE_MEM_UNDEFINED(np, size); | ||||||
| 		sz *= num; | 	return np; | ||||||
| 		off = sz - psize; |  | ||||||
| 	} |  | ||||||
| 	if ((ret = malloc(sz)) != NULL) { |  | ||||||
| 		VGMEMP_ALLOC(env, ret, sz); |  | ||||||
| 		if (!(env->me_flags & MDB_NOMEMINIT)) { |  | ||||||
| 			memset((char *)ret + off, 0, psize); |  | ||||||
| 			ret->mp_pad = 0; |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		txn->mt_flags |= MDB_TXN_ERROR; |  | ||||||
| 	} |  | ||||||
| 	return ret; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Free a single page. | /** Free a single page. | ||||||
|  * Saves single pages to a list, for future reuse. |  * Saves single pages to a list, for future reuse. | ||||||
|  * (This is not used for multi-page overflow pages.) |  * (This is not used for multi-page overflow pages.) | ||||||
| @@ -1832,7 +1840,7 @@ static void | |||||||
| mdb_page_free(MDB_env *env, MDB_page *mp) | mdb_page_free(MDB_env *env, MDB_page *mp) | ||||||
| { | { | ||||||
| 	mp->mp_next = env->me_dpages; | 	mp->mp_next = env->me_dpages; | ||||||
| 	VGMEMP_FREE(env, mp); | 	VALGRIND_MEMPOOL_FREE(env, mp); | ||||||
| 	env->me_dpages = mp; | 	env->me_dpages = mp; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1844,7 +1852,7 @@ mdb_dpage_free(MDB_env *env, MDB_page *dp) | |||||||
| 		mdb_page_free(env, dp); | 		mdb_page_free(env, dp); | ||||||
| 	} else { | 	} else { | ||||||
| 		/* large pages just get freed directly */ | 		/* large pages just get freed directly */ | ||||||
| 		VGMEMP_FREE(env, dp); | 		VALGRIND_MEMPOOL_FREE(env, dp); | ||||||
| 		free(dp); | 		free(dp); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -2497,7 +2505,14 @@ search_done: | |||||||
| 	} else { | 	} else { | ||||||
| 		txn->mt_next_pgno = pgno + num; | 		txn->mt_next_pgno = pgno + num; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | #ifdef LDAP_MEMORY_DEBUG | ||||||
|  | 	memset(np, 111, env->me_psize * num); | ||||||
|  | #endif | ||||||
|  | 	VALGRIND_MAKE_MEM_UNDEFINED(np, env->me_psize * num); | ||||||
|  |  | ||||||
| 	np->mp_pgno = pgno; | 	np->mp_pgno = pgno; | ||||||
|  | 	np->mp_pad = 0; | ||||||
| 	mdb_page_dirty(txn, np); | 	mdb_page_dirty(txn, np); | ||||||
| 	*mp = np; | 	*mp = np; | ||||||
|  |  | ||||||
| @@ -4355,7 +4370,7 @@ mdb_env_create(MDB_env **env) | |||||||
| #endif | #endif | ||||||
| 	e->me_pid = getpid(); | 	e->me_pid = getpid(); | ||||||
| 	GET_PAGESIZE(e->me_os_psize); | 	GET_PAGESIZE(e->me_os_psize); | ||||||
| 	VGMEMP_CREATE(e,0,0); | 	VALGRIND_CREATE_MEMPOOL(e,0,0); | ||||||
| 	*env = e; | 	*env = e; | ||||||
| 	return MDB_SUCCESS; | 	return MDB_SUCCESS; | ||||||
| } | } | ||||||
| @@ -4451,6 +4466,11 @@ mdb_env_map(MDB_env *env, void *addr) | |||||||
| 		return ErrCode(); | 		return ErrCode(); | ||||||
| #endif /* _WIN32 */ | #endif /* _WIN32 */ | ||||||
|  |  | ||||||
|  | #ifdef USE_VALGRIND | ||||||
|  | 	env->me_valgrind_handle = VALGRIND_CREATE_BLOCK( | ||||||
|  | 				env->me_map, env->me_mapsize, "lmdb"); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	return MDB_SUCCESS; | 	return MDB_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -4476,6 +4496,10 @@ mdb_env_set_mapsize(MDB_env *env, size_t size) | |||||||
| 				size = minsize; | 				size = minsize; | ||||||
| 		} | 		} | ||||||
| 		munmap(env->me_map, env->me_mapsize); | 		munmap(env->me_map, env->me_mapsize); | ||||||
|  | #ifdef USE_VALGRIND | ||||||
|  | 		VALGRIND_DISCARD(env->me_valgrind_handle); | ||||||
|  | 		env->me_valgrind_handle = -1; | ||||||
|  | #endif | ||||||
| 		env->me_mapsize = size; | 		env->me_mapsize = size; | ||||||
| 		old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL; | 		old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL; | ||||||
| 		rc = mdb_env_map(env, old); | 		rc = mdb_env_map(env, old); | ||||||
| @@ -5364,6 +5388,10 @@ mdb_env_close0(MDB_env *env, int excl) | |||||||
|  |  | ||||||
| 	if (env->me_map) { | 	if (env->me_map) { | ||||||
| 		munmap(env->me_map, env->me_mapsize); | 		munmap(env->me_map, env->me_mapsize); | ||||||
|  | #ifdef USE_VALGRIND | ||||||
|  | 		VALGRIND_DISCARD(env->me_valgrind_handle); | ||||||
|  | 		env->me_valgrind_handle = -1; | ||||||
|  | #endif | ||||||
| 	} | 	} | ||||||
| 	if (env->me_mfd != env->me_fd && env->me_mfd != INVALID_HANDLE_VALUE) | 	if (env->me_mfd != env->me_fd && env->me_mfd != INVALID_HANDLE_VALUE) | ||||||
| 		(void) close(env->me_mfd); | 		(void) close(env->me_mfd); | ||||||
| @@ -5426,9 +5454,9 @@ mdb_env_close(MDB_env *env) | |||||||
| 	if (env == NULL) | 	if (env == NULL) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	VGMEMP_DESTROY(env); | 	VALGRIND_DESTROY_MEMPOOL(env); | ||||||
| 	while ((dp = env->me_dpages) != NULL) { | 	while ((dp = env->me_dpages) != NULL) { | ||||||
| 		VGMEMP_DEFINED(&dp->mp_next, sizeof(dp->mp_next)); | 		VALGRIND_MAKE_MEM_DEFINED(&dp->mp_next, sizeof(dp->mp_next)); | ||||||
| 		env->me_dpages = dp->mp_next; | 		env->me_dpages = dp->mp_next; | ||||||
| 		free(dp); | 		free(dp); | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user