为什么 libc 中的内存分配没有路由到我的分配包装器?

Why are Memory allocations within libc are not routed to my allocation wrappers?

我正在尝试在 CentOS 上提供内存包装器并使用 clang compiler/linker。我为分配函数(malloc 等)编写了包装器,并使用 -Wl,-wrap,malloc 重新路由了调用。

一切正常,我可以看到它在运行。 void* mem = malloc(10); // routes to __wrap_malloc free(mem);// routes to __wrap_free

但是,我看到的问题是,在 libc 中分配的任何内存都没有被路由到我的包装器,而是应用程序正在进行的免费调用被拦截(并因此崩溃)。例如,

char* newStr = strdup("foo"); // The internal malloc in libcdoes not come to wrapper free(newStr); // The free call makes it to the wrapper

我的程序是用 C++ 编写的。我创建了一个 mallocimpl.cpp 并做了类似

的事情

extern "C"{ void* __wrap_malloc(size_t size) { // Route memory via custom memory allocator } //Similarly, __wrap_calloc, __wrap_realloc, __wrap_memalign and __wrap_free

知道我做错了什么吗?我需要任何特殊的 compiler/linker 标记吗?

提前致谢。

保证匹配 malloc / free 的唯一方法是重新编译所有内容,包括 libc。这对你来说可能不切实际,所以你最好的选择是以某种方式跟踪你的 malloc 包装器分配的内存,然后适当地自行释放它或在你的 free 包装器中调用 __real_free 基于关于如何分配内存。

glibc 中有一些特殊的 "hooks"(__malloc_hook__realloc_hook__free_hook__memalign_hook)来捕获 glibc 的所有 malloc:https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html

The GNU C Library lets you modify the behavior of malloc, realloc, and free by specifying appropriate hook functions. You can use these hooks to help you debug programs that use dynamic memory allocation, for example.

挂钩不安全,在手册页中标记为已弃用。 An alternative for the deprecated __malloc_hook functionality of glibc

中列出了一些变体

此外,检查 jemalloctcmalloc 和其他替代 malloc 如何实现它们的 "preloading/linking of special library" 来替换 glibc malloc。

替换 glibc malloc 实现的推荐方法是 ELF 符号插入:

这样,您不必重新编译所有内容,包括 glibc,一旦 glibc 删除 malloc 挂钩,您的 malloc 替换仍将被调用。

如果不重新编译(或至少重写)所有内容,__wrap 方法将不起作用,因为所有其他库(包括 glibc)将使用 non-wrapped 符号。