在C中为malloc和free创建包装函数
我正在尝试为C中的在C中为malloc和free创建包装函数,c,memory-management,memory-leaks,malloc,C,Memory Management,Memory Leaks,Malloc,我正在尝试为C中的free和malloc创建包装函数,以帮助通知我内存泄漏。有人知道如何声明这些函数吗?因此,当我调用malloc()和free()时,它将调用我的自定义函数,而不是标准库函数?如果您为malloc()和free()定义自己的函数并将其与应用程序显式链接,您的函数应优先于库中的函数使用 但是,名为“malloc”的函数随后不能调用库malloc函数,因为在“c”中没有单独名称空间的概念。换句话说,您必须实现malloc的内部结构并释放自己 另一种方法是编写调用标准库函数的函数my
free
和malloc
创建包装函数,以帮助通知我内存泄漏。有人知道如何声明这些函数吗?因此,当我调用malloc()
和free()
时,它将调用我的自定义函数,而不是标准库函数?如果您为malloc()和free()定义自己的函数并将其与应用程序显式链接,您的函数应优先于库中的函数使用
但是,名为“malloc”的函数随后不能调用库malloc函数,因为在“c”中没有单独名称空间的概念。换句话说,您必须实现malloc的内部结构并释放自己
另一种方法是编写调用标准库函数的函数my_malloc()和my_free()。这意味着任何调用malloc的代码都必须更改为调用my_xxx函数。您有几个选项:
gcc
的GLIBC
,首选方法是使用。它不仅允许您指定自定义malloc
和free
,还可以通过堆栈上的返回地址识别调用方malloc
和free
定义为可执行文件中原始分配例程的包装,这将“覆盖”libc中的版本。在包装器内部,您可以调用原始的malloc
实现,您可以使用RTLD\u NEXT
句柄查找该实现。定义包装函数的应用程序或库需要链接到-ldl
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
void* malloc(size_t sz)
{
void *(*libc_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc");
printf("malloc\n");
return libc_malloc(sz);
}
void free(void *p)
{
void (*libc_free)(void*) = dlsym(RTLD_NEXT, "free");
printf("free\n");
libc_free(p);
}
int main()
{
free(malloc(10));
return 0;
}
DYLD\u INSERT\u库
环境变量LD_PRELOAD=mymalloc.so ./exe
如果您的目标是消除内存泄漏,一种更简单、侵入性更小的方法是使用(免费)或(昂贵)之类的工具。如果您使用的是Linux,则可以使用malloc_hook()(与GNU glibc一起使用)。此函数允许您在调用实际malloc之前让malloc调用您的函数。手册页有一个关于如何使用它的示例。在C中,我使用的方法类似于:
#define malloc(x) _my_malloc(x, __FILE__, __LINE__)
#define free(x) _my_free(x)
这使我能够毫不费力地检测分配内存的行和文件。它应该是跨平台的,但如果已经定义了宏,则会遇到问题(只有在使用另一个内存泄漏检测器时才会出现这种情况)
如果你想在C++中实现同样的过程,程序会更多,但是使用相同的技巧。 如果你只谈论你可以控制的内存,也就是说,你可以自己控制和释放内存,你可以看看。也许这就是你要写的东西,所以你可以节省一些时间。它有一个非常自由的许可证,如果这对你很重要的话
我个人在一个项目中使用它来查找内存泄漏,好处是它比valgrind快得多,但是它没有那么强大,所以你没有得到完整的调用堆栈。这里有一组包装函数,我用了很多年(当我使用C时仍然如此)来检测未释放的内存,多次释放内存,对空闲内存、缓冲区溢出/下溢和释放未分配内存的引用 他们已经存在了25年,并证明了自己 您可以使用宏预处理器重新定义malloc并免费使用mem包,但我建议您不要这样做,因为它不会像strdup那样将库调用重定向到malloc。您可以使用LD_PRELOAD执行包装和“覆盖”函数-类似于前面显示的示例
LD_PRELOAD=/path.../lib_fake_malloc.so ./app
但我建议您“稍微”聪明一点,我的意思是给dlsym打一次电话
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
void* malloc(size_t size)
{
static void* (*real_malloc)(size_t) = NULL;
if (!real_malloc)
real_malloc = dlsym(RTLD_NEXT, "malloc");
void *p = real_malloc(size);
fprintf(stderr, "malloc(%d) = %p\n", size, p);
return p;
}
我同意他们的观点,这是一个“微不足道的例子”:。甚至不需要dlsym
让我在我的“男性身份”页面中再引用一部分:
我希望,描述是完整的,并展示了如何使用这些东西。在我的例子中,我需要将memalign/aligned\u malloc包装在malloc下。在尝试了其他解决方案后,我最终实现了下面列出的解决方案。它似乎工作得很好
/*
*使用静态的malloc和free的链接时间插入
*链接器的(ld)“--wrap symbol”标志。
*
*使用“-Wl,--wrap,malloc-Wl,--wrap,free”编译可执行文件。
*这告诉链接器将对malloc的引用解析为
*_uuuwrap_malloc、free as uuu wrap_free、real_umalloc as malloc,以及
*_uuureal_u免费。
*/
#包括
void*\uuuu real\u malloc(尺寸大小);
无效uu真实u自由(无效*ptr);
/*
*\uuuu wrap\u malloc-malloc包装函数
*/
无效*\uuuuuuuu包裹\uuMalloc(尺寸)
{
void*ptr=\uuuuureal\umalloc(大小);
printf(“malloc(%d)=%p\n”,大小,ptr);
返回ptr;
}
/*
*_u_wrap_free-free包装函数
*/
无效uu包裹u自由(无效*ptr)
{
__不动产(ptr);
printf(“免费(%p)\n”,ptr);
}
如果您是自定义malloc
和free
的唯一客户机(即,您没有试图为其他库中的代码修补这些方法),那么您可以使用依赖项注入
\ifndef分配器
#定义分配器
#包括
结构分配器;
类型定义结构{
void*(*allocate)(结构分配器*Allocator,size\u t size);
void(*free)(结构分配器*分配器,void*对象);
}分配表;
类型定义结构分配器{
常量分配器vtable*vptr;
}分配器;
类型定义结构{
超级分配器;
字符*缓冲区;
尺寸偏差;
容量大小;
}缓冲分配器;
void BufferedAllocator_init(BufferedAllocator*分配器,char*缓冲区,大小\u t容量);
typedef分配器MallocAllocator;
void MallocAllocator_init(MallocAllocator*分配器);
void*Allocator\u allocate(分配器*Allocator,size\u t size);
无效分配器
void *
__wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}
--wrap=symbol
Use a wrapper function for symbol.
Any undefined reference to symbol will be resolved to "__wrap_symbol".
Any undefined reference to "__real_symbol" will be resolved to symbol.
/*
* Link-time interposition of malloc and free using the static
* linker's (ld) "--wrap symbol" flag.
*
* Compile the executable using "-Wl,--wrap,malloc -Wl,--wrap,free".
* This tells the linker to resolve references to malloc as
* __wrap_malloc, free as __wrap_free, __real_malloc as malloc, and
* __real_free as free.
*/
#include <stdio.h>
void *__real_malloc(size_t size);
void __real_free(void *ptr);
/*
* __wrap_malloc - malloc wrapper function
*/
void *__wrap_malloc(size_t size)
{
void *ptr = __real_malloc(size);
printf("malloc(%d) = %p\n", size, ptr);
return ptr;
}
/*
* __wrap_free - free wrapper function
*/
void __wrap_free(void *ptr)
{
__real_free(ptr);
printf("free(%p)\n", ptr);
}