--- a/runtime/allocator.cpp +++ b/runtime/allocator.cpp @@ -9,6 +9,36 @@ #include #include +static void *(* volatile malloc_hook_dummy)(size_t, const void *); +static decltype(malloc_hook_dummy) *malloc_hook_ptr; +static void *(* volatile realloc_hook_dummy)(void *, size_t, const void *); +static decltype(realloc_hook_dummy) *realloc_hook_ptr; +static void (* volatile free_hook_dummy)(void *, const void *); +static decltype(free_hook_dummy) *free_hook_ptr; +static void *(* volatile memalign_hook_dummy)(size_t, size_t, const void *); +static decltype(memalign_hook_dummy) *memalign_hook_ptr; + +static void malloc_hook_init(void) { + static bool initialized = false; + if (initialized) return; + void *libc_handle = dlopen("libc.so", RTLD_NOW); + if (libc_handle != NULL) { + malloc_hook_ptr = (decltype(malloc_hook_ptr))dlsym(libc_handle, "__malloc_hook"); + realloc_hook_ptr = (decltype(realloc_hook_ptr))dlsym(libc_handle, "__realloc_hook"); + free_hook_ptr = (decltype(free_hook_ptr))dlsym(libc_handle, "__free_hook"); + memalign_hook_ptr = (decltype(memalign_hook_ptr))dlsym(libc_handle, "__memalign_hook"); + } + if (malloc_hook_ptr == NULL) + malloc_hook_ptr = &malloc_hook_dummy; + if (realloc_hook_ptr == NULL) + realloc_hook_ptr = &realloc_hook_dummy; + if (free_hook_ptr == NULL) + free_hook_ptr = &free_hook_dummy; + if (memalign_hook_ptr == NULL) + memalign_hook_ptr = &memalign_hook_dummy; + initialized = true; +} + #include "common/algorithms/find.h" #include "common/containers/final_action.h" #include "common/macos-ports.h" @@ -246,10 +276,11 @@ void switch_hooks(bool malloc_hooks_are_replaced_before) noexcept { php_assert(malloc_hooks_are_replaced_before == malloc_hooks_are_replaced_); CriticalSectionGuard critical_section; - std::swap(malloc_hook_, __malloc_hook); - std::swap(realloc_hook_, __realloc_hook); - std::swap(memalign_hook_, __memalign_hook); - std::swap(free_hook_, __free_hook); + malloc_hook_init(); + std::swap(malloc_hook_, *malloc_hook_ptr); + std::swap(realloc_hook_, *realloc_hook_ptr); + std::swap(memalign_hook_, *memalign_hook_ptr); + std::swap(free_hook_, *free_hook_ptr); malloc_hooks_are_replaced_ = !malloc_hooks_are_replaced_; } @@ -274,10 +305,10 @@ return script_allocator_free(ptr); }} {} - decltype(__malloc_hook) malloc_hook_{nullptr}; - decltype(__realloc_hook) realloc_hook_{nullptr}; - decltype(__memalign_hook) memalign_hook_{nullptr}; - decltype(__free_hook) free_hook_{nullptr}; + decltype(malloc_hook_dummy) malloc_hook_{nullptr}; + decltype(realloc_hook_dummy) realloc_hook_{nullptr}; + decltype(memalign_hook_dummy) memalign_hook_{nullptr}; + decltype(free_hook_dummy) free_hook_{nullptr}; bool malloc_hooks_are_replaced_{false}; };