fix windows dynamic malloc overried when both ucrtbase and msvcrt are loaded; also fix virtualalloc2 on 32-bit

This commit is contained in:
daan 2019-07-03 13:00:43 -07:00
parent 158705815e
commit 9390642879
3 changed files with 9 additions and 7 deletions

View file

@ -526,7 +526,7 @@ static void mi_module_resolve(HMODULE mod) {
// see if any patches apply // see if any patches apply
for (size_t i = 0; patches[i].name != NULL; i++) { for (size_t i = 0; patches[i].name != NULL; i++) {
mi_patch_t* patch = &patches[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); void* addr = GetProcAddress(mod, patch->name);
if (addr != NULL) { if (addr != NULL) {
// found it! set the address // found it! set the address
@ -554,9 +554,11 @@ static bool mi_patches_resolve(void) {
size_t count = needed / sizeof(HMODULE); size_t count = needed / sizeof(HMODULE);
size_t ucrtbase_index = 0; size_t ucrtbase_index = 0;
size_t mimalloc_index = 0; size_t mimalloc_index = 0;
// iterate through the loaded modules // iterate through the loaded modules; do this from the end so we prefer the
for (size_t i = 0; i < count; i++) { // first loaded DLL as sometimes both "msvcr" and "ucrt" are both loaded and we should
HMODULE mod = modules[i]; // override "ucrt" in that situation.
for (size_t i = count; i > 0; i--) {
HMODULE mod = modules[i-1];
char filename[MAX_PATH] = { 0 }; char filename[MAX_PATH] = { 0 };
DWORD slen = GetModuleFileName(mod, filename, MAX_PATH); DWORD slen = GetModuleFileName(mod, filename, MAX_PATH);
if (slen > 0 && slen < 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); const char* basename = (lastsep==NULL ? filename : lastsep+1);
if (i==0 // main module to allow static crt linking if (i==0 // main module to allow static crt linking
|| _strnicmp(basename, "ucrt", 4) == 0 // new ucrtbase.dll in windows 10 || _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) // remember indices so we can check load order (in debug mode)
if (_stricmp(basename, MIMALLOC_NAME) == 0) mimalloc_index = i; if (_stricmp(basename, MIMALLOC_NAME) == 0) mimalloc_index = i;

View file

@ -62,7 +62,7 @@ static size_t mi_os_good_alloc_size(size_t size, size_t alignment) {
#if defined(_WIN32) #if defined(_WIN32)
// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. // 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. // 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; static VirtualAlloc2Ptr pVirtualAlloc2 = NULL;
void _mi_os_init(void) { void _mi_os_init(void) {

View file

@ -13,7 +13,7 @@ void free_p() {
} }
int main() { int main() {
mi_stats_reset(); mi_stats_reset();
atexit(free_p); atexit(free_p);
void* p1 = malloc(78); void* p1 = malloc(78);
void* p2 = malloc(24); void* p2 = malloc(24);