覆盖cpp程序中的malloc和new调用

问题描述 投票:0回答:4

我想调用我的自定义 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

这适用于 gcc 的 .c 文件,但不适用于 g++ 和 .cpp 文件。有什么问题吗?

2. 另外,我不知道如何覆盖新呼叫?

c++ linker g++ malloc ld
4个回答
3
投票

为什么
g++
不能与
-Wl,--wrap,malloc
一起使用?

g++
意味着 C++,C++ ABI 与 C ABI 不同。所以你需要在
extern "C"
__real_malloc
周围添加
__wrap_malloc
:

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 编译器无需将名称翻译为程序集。变化很大。 此编译器资源管理器示例显示 x86 msvc 编译器在函数名称前插入 _,而其他 3 个编译器(x64 msvc、x86-64 gcc 和 x86-64 clang)保留 C 中定义的原始名称。

-Wl,--wrap,malloc

是传递给链接器的选项,它要求链接器查找名为

__wrap_malloc
的函数。使用
extern "C"
,g++ 会生成名称,就像在 C 源文件中定义该函数一样,以便链接器可以找到它。
如何覆盖

new

您可以专门针对某个类覆盖 

new

,或提供全局

new
。请参阅
https://en.cppreference.com/w/cpp/memory/new/operator_new


0
投票

#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


-1
投票
-Wl,--wrap,malloc

不起作用。

但请注意,在你让它工作后,你的代码很可能由于堆栈溢出而

崩溃

这是因为

printf

可以(并且在某些条件下)调用

malloc
本身,当这种情况发生时,很可能会出现无限递归。
    


-1
投票
这里是 Microsoft 的

mimalloc(MIT 许可证)覆盖的所有函数的列表 // C void* malloc(size_t size); void* calloc(size_t size, size_t n); void* realloc(void* p, size_t newsize); void free(void* p); void* aligned_alloc(size_t alignment, size_t size); char* strdup(const char* s); char* strndup(const char* s, size_t n); char* realpath(const char* fname, char* resolved_name); // C++ void operator delete(void* p); void operator delete[](void* p); void* operator new(std::size_t n) noexcept(false); void* operator new[](std::size_t n) noexcept(false); void* operator new( std::size_t n, std::align_val_t align) noexcept(false); void* operator new[]( std::size_t n, std::align_val_t align) noexcept(false); void* operator new ( std::size_t count, const std::nothrow_t& tag); void* operator new[]( std::size_t count, const std::nothrow_t& tag); void* operator new ( std::size_t count, std::align_val_t al, const std::nothrow_t&); void* operator new[]( std::size_t count, std::align_val_t al, const std::nothrow_t&); // Posix int posix_memalign(void** p, size_t alignment, size_t size); // Linux void* memalign(size_t alignment, size_t size); void* valloc(size_t size); void* pvalloc(size_t size); size_t malloc_usable_size(void *p); void* reallocf(void* p, size_t newsize); // macOS void vfree(void* p); size_t malloc_size(const void* p); size_t malloc_good_size(size_t size); // BSD void* reallocarray( void* p, size_t count, size_t size ); void* reallocf(void* p, size_t newsize); void cfree(void* p); // NetBSD int reallocarr(void* p, size_t count, size_t size); // Windows void* _expand(void* p, size_t newsize); size_t _msize(void* p); void* _malloc_dbg(size_t size, int block_type, const char* fname, int line); void* _realloc_dbg(void* p, size_t newsize, int block_type, const char* fname, int line); void* _calloc_dbg(size_t count, size_t size, int block_type, const char* fname, int line); void* _expand_dbg(void* p, size_t size, int block_type, const char* fname, int line); size_t _msize_dbg(void* p, int block_type); void _free_dbg(void* p, int block_type);

这些覆盖被重定向到 
mimalloc/src/alloc-override.c

中的 mimalloc 库。一些重要的功能是: mi_malloc mi_calloc mi_realloc mi_reallocarr mi_reallocf mi_reallocarray mi_valloc mi_free mi_free_aligned mi_cfree mi_new mi_new_nothrow mi_new_aligned mi_new_aligned_nothrow mi_posix_memalign mi_memalign mi_aligned_alloc mi_pvalloc

因此,要覆盖所有相关功能,自定义这些条目可能是另一个好方法。

© www.soinside.com 2019 - 2024. All rights reserved.