-
Notifications
You must be signed in to change notification settings - Fork 116
Detours implementation of overriding CRT #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
7e678d6
to
c64e2a1
Compare
@NeilMonday I wonder if you had any thoughts on this PR? |
671efbc
to
68d4180
Compare
This commit adds an override to Windows for replacing the CRT malloc/free etc routines.
I wonder if we should adjust the behavior of malloc to interact with the alloc failure hooks (aka new handlers) on windows. Otherwise, after detour is installed, new handlers may not be invoked as excepted. The UCRT way of doing this: // This function implements the logic of malloc(). It is called directly by the
// malloc() function in the Release CRT and is called by the debug heap in the
// Debug CRT.
//
// This function must be marked noinline, otherwise malloc and
// _malloc_base will have identical COMDATs, and the linker will fold
// them when calling one from the CRT. This is necessary because malloc
// needs to support users patching in custom implementations.
extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _malloc_base(size_t const size)
{
// Ensure that the requested size is not too large:
_VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
// Ensure we request an allocation of at least one byte:
size_t const actual_size = size == 0 ? 1 : size;
for (;;)
{
void* const block = HeapAlloc(__acrt_heap, 0, actual_size);
if (block)
return block;
// Otherwise, see if we need to call the new handler, and if so call it.
// If the new handler fails, just return nullptr:
if (_query_new_mode() == 0 || !_callnewh(actual_size))
{
errno = ENOMEM;
return nullptr;
}
// The new handler was successful; try to allocate again...
}
} |
That is a great observation. I have a few thoughts:
I think with these changes we will be able to not impact performance, and meet the spec. Does that make sense to you @SchrodingerZhu? |
The plan sounds solid to me. Just a minor comment:
I think UCRT is calling the new handler regardless of whether the toplevel function is using C-API or C++-API. As demonstrated in the code comment of UCRT |
I thought it would only call it in the case of We also really need to implement char* a = (char*)malloc(23);
char* b = _recalloc(a, 32);
assert(b[26] == 0); This is hard to achieve with a sizeclass allocator as we don't have the accurate size information around. So I would like to leave |
I see. it makes sense then. |
#791 means this can now be extended to correctly cover the Windows CRT |
This commit adds an override to Windows for replacing the CRT malloc/free etc routines.
This is stacked on top of #774.