在 cpp 程序中覆盖 malloc 和新调用
override malloc and new calls in cpp program
我想调用我的自定义 malloc/new 调用而不是标准库函数。
1.对于malloc,我有这个小程序
#include <stdio.h>
#include <stdlib.h>
void *__real_malloc(size_t size);
void *__wrap_malloc(size_t size)
{
void *ptr = __real_malloc(size);
printf("malloc(%ld) = %p\n", size, ptr);
return ptr;
}
int main(void) {
int* ptr = (int*) malloc(sizeof(int));
return 0;
}
我用下面的命令编译
g++ -Wl,--wrap,malloc main.cpp
但是低于错误
/usr/bin/ld: /tmp/ccnB04KY.o: in function `__wrap_malloc(unsigned long)':
b3.cpp:(.text+0x18): undefined reference to `__real_malloc(unsigned long)'
/usr/bin/ld: /tmp/ccnB04KY.o: in function `main':
b3.cpp:(.text+0x54): undefined reference to `__wrap_malloc'
collect2: error: ld returned 1 exit status
这适用于 .c 文件的 gcc,但不适用于 g++ 和 .cpp 文件。有什么问题?
2. 另外我不知道如何覆盖新呼叫?
为什么 g++
不能与 -Wl,--wrap,malloc
一起使用?
g++
适用于C++,C++ ABI不同于C ABI。所以你需要在 __real_malloc
和 __wrap_malloc
:
周围添加 extern "C"
extern "C" {
void *__real_malloc(size_t size);
void *__wrap_malloc(size_t size) {
void *ptr = __real_malloc(size);
printf("malloc(%ld) = %p\n", size, ptr);
return ptr;
}
}
C++ 将名称重写为某种随机(至少看起来如此)字符串以避免冲突,而 C 经常 只是在“C”之前插入 _
name 在程序集中创建一个名称。 (此命名约定称为 _cdecl
,最常用。)extern "C"
强制 C++ 编译器根据 C 的约定生成名称。有关详细信息,请参阅 https://en.wikipedia.org/wiki/Name_mangling。
如何覆盖 new
?
您可以专门为 class 覆盖 new
,或提供全局 new
。参见 https://en.cppreference.com/w/cpp/memory/new/operator_new。
如果您使用的是 glibc,那么您可以使用 malloc 的 GNU 扩展:man malloc_hook
#include <malloc.h>
void *(*__malloc_hook)(size_t size, const void *caller);
void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);
void *(*__memalign_hook)(size_t alignment, size_t size,
const void *caller);
void (*__free_hook)(void *ptr, const void *caller);
void (*__malloc_initialize_hook)(void);
void (*__after_morecore_hook)(void);
对于new
你可以提供一个全局的新的。参见 https://en.cppreference.com/w/cpp/memory/new/operator_new。
其他答案说明了为什么 -Wl,--wrap,malloc
不起作用。
但请注意,在您使其工作后,您的代码很可能会由于堆栈溢出而崩溃。
这是因为 printf
可以(并且在某些条件下确实如此)调用 malloc
自身,当发生这种情况时,很可能会出现无限递归。
我想调用我的自定义 malloc/new 调用而不是标准库函数。 1.对于malloc,我有这个小程序
#include <stdio.h>
#include <stdlib.h>
void *__real_malloc(size_t size);
void *__wrap_malloc(size_t size)
{
void *ptr = __real_malloc(size);
printf("malloc(%ld) = %p\n", size, ptr);
return ptr;
}
int main(void) {
int* ptr = (int*) malloc(sizeof(int));
return 0;
}
我用下面的命令编译
g++ -Wl,--wrap,malloc main.cpp
但是低于错误
/usr/bin/ld: /tmp/ccnB04KY.o: in function `__wrap_malloc(unsigned long)':
b3.cpp:(.text+0x18): undefined reference to `__real_malloc(unsigned long)'
/usr/bin/ld: /tmp/ccnB04KY.o: in function `main':
b3.cpp:(.text+0x54): undefined reference to `__wrap_malloc'
collect2: error: ld returned 1 exit status
这适用于 .c 文件的 gcc,但不适用于 g++ 和 .cpp 文件。有什么问题?
2. 另外我不知道如何覆盖新呼叫?
为什么 g++
不能与 -Wl,--wrap,malloc
一起使用?
g++
适用于C++,C++ ABI不同于C ABI。所以你需要在 __real_malloc
和 __wrap_malloc
:
extern "C"
extern "C" {
void *__real_malloc(size_t size);
void *__wrap_malloc(size_t size) {
void *ptr = __real_malloc(size);
printf("malloc(%ld) = %p\n", size, ptr);
return ptr;
}
}
C++ 将名称重写为某种随机(至少看起来如此)字符串以避免冲突,而 C 经常 只是在“C”之前插入 _
name 在程序集中创建一个名称。 (此命名约定称为 _cdecl
,最常用。)extern "C"
强制 C++ 编译器根据 C 的约定生成名称。有关详细信息,请参阅 https://en.wikipedia.org/wiki/Name_mangling。
如何覆盖 new
?
您可以专门为 class 覆盖 new
,或提供全局 new
。参见 https://en.cppreference.com/w/cpp/memory/new/operator_new。
如果您使用的是 glibc,那么您可以使用 malloc 的 GNU 扩展:man malloc_hook
#include <malloc.h>
void *(*__malloc_hook)(size_t size, const void *caller);
void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);
void *(*__memalign_hook)(size_t alignment, size_t size,
const void *caller);
void (*__free_hook)(void *ptr, const void *caller);
void (*__malloc_initialize_hook)(void);
void (*__after_morecore_hook)(void);
对于new
你可以提供一个全局的新的。参见 https://en.cppreference.com/w/cpp/memory/new/operator_new。
其他答案说明了为什么 -Wl,--wrap,malloc
不起作用。
但请注意,在您使其工作后,您的代码很可能会由于堆栈溢出而崩溃。
这是因为 printf
可以(并且在某些条件下确实如此)调用 malloc
自身,当发生这种情况时,很可能会出现无限递归。