From 93906428798ff6f4e1b71bf2afc087f6920dddf6 Mon Sep 17 00:00:00 2001 From: daan Date: Wed, 3 Jul 2019 13:00:43 -0700 Subject: [PATCH] fix windows dynamic malloc overried when both ucrtbase and msvcrt are loaded; also fix virtualalloc2 on 32-bit --- src/alloc-override-win.c | 12 +++++++----- src/os.c | 2 +- test/main-override.cpp | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/alloc-override-win.c b/src/alloc-override-win.c index 7158e920..9c091389 100644 --- a/src/alloc-override-win.c +++ b/src/alloc-override-win.c @@ -526,7 +526,7 @@ static void mi_module_resolve(HMODULE mod) { // see if any patches apply for (size_t i = 0; patches[i].name != NULL; i++) { mi_patch_t* patch = &patches[i]; - if (!patch->applied && patch->original==NULL) { + if (!patch->applied && patch->original==NULL) { // we apply only the first found dll void* addr = GetProcAddress(mod, patch->name); if (addr != NULL) { // found it! set the address @@ -554,9 +554,11 @@ static bool mi_patches_resolve(void) { size_t count = needed / sizeof(HMODULE); size_t ucrtbase_index = 0; size_t mimalloc_index = 0; - // iterate through the loaded modules - for (size_t i = 0; i < count; i++) { - HMODULE mod = modules[i]; + // iterate through the loaded modules; do this from the end so we prefer the + // first loaded DLL as sometimes both "msvcr" and "ucrt" are both loaded and we should + // override "ucrt" in that situation. + for (size_t i = count; i > 0; i--) { + HMODULE mod = modules[i-1]; char filename[MAX_PATH] = { 0 }; DWORD slen = GetModuleFileName(mod, filename, MAX_PATH); if (slen > 0 && slen < MAX_PATH) { @@ -566,7 +568,7 @@ static bool mi_patches_resolve(void) { const char* basename = (lastsep==NULL ? filename : lastsep+1); if (i==0 // main module to allow static crt linking || _strnicmp(basename, "ucrt", 4) == 0 // new ucrtbase.dll in windows 10 - || _strnicmp(basename, "msvcr", 5) == 0) // older runtimes + || _strnicmp(basename, "msvcr", 5) == 0) // older runtimes { // remember indices so we can check load order (in debug mode) if (_stricmp(basename, MIMALLOC_NAME) == 0) mimalloc_index = i; diff --git a/src/os.c b/src/os.c index d952726a..2957e0f9 100644 --- a/src/os.c +++ b/src/os.c @@ -62,7 +62,7 @@ static size_t mi_os_good_alloc_size(size_t size, size_t alignment) { #if defined(_WIN32) // We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. // So, we need to look it up dynamically to run on older systems. -typedef PVOID (*VirtualAlloc2Ptr)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG ); +typedef PVOID (__stdcall *VirtualAlloc2Ptr)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG ); static VirtualAlloc2Ptr pVirtualAlloc2 = NULL; void _mi_os_init(void) { diff --git a/test/main-override.cpp b/test/main-override.cpp index 406d3bea..e24ed6d3 100644 --- a/test/main-override.cpp +++ b/test/main-override.cpp @@ -13,7 +13,7 @@ void free_p() { } int main() { - mi_stats_reset(); + mi_stats_reset(); atexit(free_p); void* p1 = malloc(78); void* p2 = malloc(24);