Repository navigation
Windows: how to override malloc / free / new / delete globally ? #700
Description
Activity
Using the static library will only override the allocations in the exe, but I think you are picking up a DLL as well, which won't have the allocations overridden.
There are some horrible things other allocators do to achieve this by rewriting things inside UCRT. But I have never gotten around to this in snmalloc.
Just going to add a comment of the various approaches I have found.
- There is minhooks
- with an example for using it with an allocator here:
https://gist.github.com/Erfan-Ahmadi/93369b8b7fbce77b1adf8e244ea33849 - and an explanation of how it works here: https://www.codeproject.com/KB/winsdk/LibMinHook.aspx
- with an example for using it with an allocator here:
- Micro-malloc has an open source override for Windows in here: https://github.com/Thermadiag/micromalloc/tree/main/micro_proxy
- tcmalloc the older version patches various functions here: https://github.com/gperftools/gperftools/blob/master/src/windows/patch_functions.cc
I don't know as I have much time to follow up on this at the moment, but adding this comment in case anyone else does. Otherwise, it is useful for me when I get more time to work on this.
- There is minhooks
jcelerier commented
on Dec 1, 2024 ContributorAuthorMore actionsI see, I thought that since mimalloc did it (https://microsoft.github.io/mimalloc/overrides.html) likely snmalloc too but I understand now that this was a bold assumption :)
jcelerier commented
on Dec 1, 2024 ContributorAuthorMore actionsThat said, what I find weird is that in the call trace I see:
frame #6: 0x00007ffbd016364b ucrtbase.dll`_free_base + 27 frame #7: 0x00007ff65dd213f0 a.exe`main + 96(I since did a -g -O0 build too and could confirm that it goes straight from my main to _free_base). I'd expect to go through snmalloc's operator delete in that case, no ?
I just looked at the static library by default creates the symbols
sn_malloc, sn_free, ...You can override the prefix by passing to CMake:
-DSNMALLOC_STATIC_LIBRARY_PREFIX=""This would create
malloc, free, ..., etc but I have sometimes had problems with this on Windows depending on other build configurations.If you don't want to override free/malloc/etc just the C++ new/delete, then you can link libsnmalloc-new-override.a instead. This I have had better success with on projects on Windows.
I am going to take a bit of time to investigate building a proper override using Detours, which would work across multiple DLLs.
SchrodingerZhu commented
on Dec 11, 2024 CollaboratorMore actionsAlso, windows has a
_set_new_handerhook which we does not yet override.Is it possible to build a snmalloc dll that exports symbols prefixed with "mi" and disguise it as "mimalloc-override.dll" for use with minject(mimalloc-redirect.dll)?
Jean-Michaël Celerier (@jcelerier) I got around to implementing the Windows heap override using Detours. If you are interested in trying it, then take a look at
This PR is, I believe, functional but very lightly tested at the moment.
- addedplatformsSupport for a particular platformSupport for a particular platform
on Jul 1, 2025 The detours implementation works for us in a purely statically linked binary, although given that scenario I'm inclined to just play whackamole with the private crt allocator symbols to avoid the overhead of the trampoline and extra detours dependency. We can just insert the extra needed symbols into our 'header only' implementation file for integrating snmalloc. Edit: nope, trying to shim _recalloc_base ended up causing reentrancy and a crash. I did find https://developercommunity.visualstudio.com/t/-msize-implementation/626773 about the _msize_base issue but sadly no movement on that in... a long time.
The simple following program crashes if linking against snmallocshim-static (MSYS2, with clang64 but reproducible on any other MinGW environment):
main.cpp:
thus I assume I am linking something incorrectly and some allocations made with ucrt are free with snmalloc or conversely which then makes ucrt scream.