mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:04:13 +08:00
mdbx: minimize the size of poisoned/unpoisoned regions to avoid ASAN hangs.
More for second case of https://github.com/erthink/libmdbx/issues/217
This commit is contained in:
parent
891d68838a
commit
1740043678
@ -11630,11 +11630,13 @@ __cold static int mdbx_setup_dxb(MDBX_env *env, const int lck_rc,
|
|||||||
mdbx_assert(env, used_bytes >= pgno2bytes(env, NUM_METAS) &&
|
mdbx_assert(env, used_bytes >= pgno2bytes(env, NUM_METAS) &&
|
||||||
used_bytes <= env->me_dxb_mmap.limit);
|
used_bytes <= env->me_dxb_mmap.limit);
|
||||||
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
if (env->me_dxb_mmap.filesize > used_bytes) {
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(env->me_map + used_bytes,
|
VALGRIND_MAKE_MEM_NOACCESS(env->me_map + used_bytes,
|
||||||
env->me_dxb_mmap.limit - used_bytes);
|
env->me_dxb_mmap.filesize - used_bytes);
|
||||||
ASAN_POISON_MEMORY_REGION(env->me_map + used_bytes,
|
ASAN_POISON_MEMORY_REGION(env->me_map + used_bytes,
|
||||||
env->me_dxb_mmap.limit - used_bytes);
|
env->me_dxb_mmap.filesize - used_bytes);
|
||||||
env->me_poison_edge = bytes2pgno(env, env->me_dxb_mmap.limit);
|
}
|
||||||
|
env->me_poison_edge = bytes2pgno(env, env->me_dxb_mmap.filesize);
|
||||||
#endif /* MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__ */
|
#endif /* MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__ */
|
||||||
|
|
||||||
//----------------------------------------- validate head & steady meta-pages
|
//----------------------------------------- validate head & steady meta-pages
|
||||||
|
35
src/osal.c
35
src/osal.c
@ -1547,7 +1547,10 @@ MDBX_INTERNAL_FUNC int mdbx_munmap(mdbx_mmap_t *map) {
|
|||||||
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
||||||
* when this memory will re-used by malloc or another mmapping.
|
* when this memory will re-used by malloc or another mmapping.
|
||||||
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */
|
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */
|
||||||
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);
|
ASAN_UNPOISON_MEMORY_REGION(map->address,
|
||||||
|
(map->filesize && map->filesize < map->limit)
|
||||||
|
? map->filesize
|
||||||
|
: map->limit);
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if (map->section)
|
if (map->section)
|
||||||
NtClose(map->section);
|
NtClose(map->section);
|
||||||
@ -1617,6 +1620,10 @@ MDBX_INTERNAL_FUNC int mdbx_mresize(const int flags, mdbx_mmap_t *map,
|
|||||||
if ((flags & MDBX_MRESIZE_MAY_UNMAP) == 0)
|
if ((flags & MDBX_MRESIZE_MAY_UNMAP) == 0)
|
||||||
return MDBX_RESULT_TRUE;
|
return MDBX_RESULT_TRUE;
|
||||||
|
|
||||||
|
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
||||||
|
* when this memory will re-used by malloc or another mmapping.
|
||||||
|
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */
|
||||||
|
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);
|
||||||
status = NtUnmapViewOfSection(GetCurrentProcess(), map->address);
|
status = NtUnmapViewOfSection(GetCurrentProcess(), map->address);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
return ntstatus2errcode(status);
|
return ntstatus2errcode(status);
|
||||||
@ -1747,11 +1754,25 @@ retry_mapview:;
|
|||||||
if (map->current != size)
|
if (map->current != size)
|
||||||
rc =
|
rc =
|
||||||
(size > map->current) ? MDBX_UNABLE_EXTEND_MAPSIZE : MDBX_RESULT_TRUE;
|
(size > map->current) ? MDBX_UNABLE_EXTEND_MAPSIZE : MDBX_RESULT_TRUE;
|
||||||
} else if (map->filesize != size) {
|
} else {
|
||||||
|
if (map->filesize != size) {
|
||||||
rc = mdbx_ftruncate(map->fd, size);
|
rc = mdbx_ftruncate(map->fd, size);
|
||||||
if (rc != MDBX_SUCCESS)
|
if (rc != MDBX_SUCCESS)
|
||||||
return rc;
|
return rc;
|
||||||
map->filesize = size;
|
map->filesize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map->current > size) {
|
||||||
|
/* Clearing asan's bitmask for the region which released in shrinking,
|
||||||
|
* since:
|
||||||
|
* - after the shrinking we will get an exception when accessing
|
||||||
|
* this region and (therefore) do not need the help of ASAN.
|
||||||
|
* - this allows us to clear the mask only within the file size
|
||||||
|
* when closing the mapping. */
|
||||||
|
ASAN_UNPOISON_MEMORY_REGION(
|
||||||
|
(char *)map->address + size,
|
||||||
|
((map->current < map->limit) ? map->current : map->limit) - size);
|
||||||
|
}
|
||||||
map->current = size;
|
map->current = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1864,7 +1885,9 @@ retry_mapview:;
|
|||||||
* when this memory will re-used by malloc or another mmapping.
|
* when this memory will re-used by malloc or another mmapping.
|
||||||
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203
|
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203
|
||||||
*/
|
*/
|
||||||
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);
|
ASAN_UNPOISON_MEMORY_REGION(map->address, (map->current < map->limit)
|
||||||
|
? map->current
|
||||||
|
: map->limit);
|
||||||
map->limit = 0;
|
map->limit = 0;
|
||||||
map->current = 0;
|
map->current = 0;
|
||||||
map->address = nullptr;
|
map->address = nullptr;
|
||||||
@ -1880,9 +1903,9 @@ retry_mapview:;
|
|||||||
VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current);
|
VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current);
|
||||||
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
||||||
* when this memory will re-used by malloc or another mmapping.
|
* when this memory will re-used by malloc or another mmapping.
|
||||||
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203
|
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */
|
||||||
*/
|
ASAN_UNPOISON_MEMORY_REGION(
|
||||||
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);
|
map->address, (map->current < map->limit) ? map->current : map->limit);
|
||||||
|
|
||||||
VALGRIND_MAKE_MEM_DEFINED(ptr, map->current);
|
VALGRIND_MAKE_MEM_DEFINED(ptr, map->current);
|
||||||
ASAN_UNPOISON_MEMORY_REGION(ptr, map->current);
|
ASAN_UNPOISON_MEMORY_REGION(ptr, map->current);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user