mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
Merge pull request #2281 from knewstimek/pr/windows-aligned-delete-fix
fix(windows): use matching deallocator for CRT aligned blocks
This commit is contained in:
2 files changed
+37
-1
No files matched your search
@@ -56,6 +56,7 @@ void *__real_malloc(size_t size);
|
||||
void *__real_calloc(size_t count, size_t size);
|
||||
void *__real_realloc(void *block, size_t size);
|
||||
void __real_free(void *block);
|
||||
void __real__aligned_free(void *block);
|
||||
char *__real_strdup(const char *text);
|
||||
size_t __real__msize(void *block);
|
||||
/* Wrappers must call __real_* for anything that is itself wrapped: a plain
|
||||
@@ -155,7 +156,9 @@ void __wrap__aligned_free(void *block) {
|
||||
mi_free(block);
|
||||
return;
|
||||
}
|
||||
__real_free(block);
|
||||
/* A CRT aligned block has its own bookkeeping header. Plain free is not
|
||||
* its matching deallocator. */
|
||||
__real__aligned_free(block);
|
||||
}
|
||||
|
||||
void *__wrap_realloc(void *block, size_t size) {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
/* ASan detection — mimalloc MI_OVERRIDE=0 under ASan, mi_process_info
|
||||
@@ -353,6 +354,34 @@ TEST(mem_rss_reflects_external_resident_memory) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* A block the CRT's _aligned_malloc made starts past the CRT's bookkeeping
|
||||
* header, so the aligned-free wrapper must return it through _aligned_free.
|
||||
* Plain free receives an interior pointer: ASan reports a bad free, and the
|
||||
* Windows heap either rejects the free (errno) or terminates the process.
|
||||
* --wrap makes __real__aligned_malloc the CRT's own allocator, so the block is
|
||||
* genuinely foreign to mimalloc. The wrapper is called by name: the routing
|
||||
* inside it is what this pins, independent of which references the linker
|
||||
* rewrites. */
|
||||
void *__real__aligned_malloc(size_t size, size_t alignment);
|
||||
void __wrap__aligned_free(void *block);
|
||||
|
||||
TEST(mem_win_aligned_free_returns_crt_block_to_crt) {
|
||||
enum { CRT_BLOCK_SIZE = 256, CRT_BLOCK_ALIGNMENT = 64 };
|
||||
unsigned char *block = __real__aligned_malloc(CRT_BLOCK_SIZE, CRT_BLOCK_ALIGNMENT);
|
||||
ASSERT_NOT_NULL(block);
|
||||
/* Without a CRT-owned block the wrapper takes its mimalloc path instead. */
|
||||
ASSERT_FALSE(mi_is_in_heap_region(block));
|
||||
ASSERT_EQ((uintptr_t)block % CRT_BLOCK_ALIGNMENT, 0);
|
||||
memset(block, 0xA5, CRT_BLOCK_SIZE);
|
||||
errno = 0;
|
||||
__wrap__aligned_free(block);
|
||||
ASSERT_EQ(errno, 0);
|
||||
ASSERT_TRUE(HeapValidate(GetProcessHeap(), 0, NULL));
|
||||
PASS();
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(mem_collect_rss_still_positive) {
|
||||
cbm_mem_init(0.5);
|
||||
cbm_mem_collect();
|
||||
@@ -1745,6 +1774,10 @@ SUITE(mem) {
|
||||
RUN_TEST(mem_rss_reflects_external_resident_memory);
|
||||
RUN_TEST(mem_collect_no_crash);
|
||||
RUN_TEST(mem_collect_rss_still_positive);
|
||||
#ifdef _WIN32
|
||||
/* Windows allocator wrappers */
|
||||
RUN_TEST(mem_win_aligned_free_returns_crt_block_to_crt);
|
||||
#endif
|
||||
/* Memory pressure simulation */
|
||||
RUN_TEST(mem_progressive_alloc_rss_increases);
|
||||
RUN_TEST(mem_free_and_collect_no_crash);
|
||||
|
||||
Reference in new issue
Block a user