38 c malloc memory-leaks memory-management
我试图创建一个包装函数free,并malloc用C来帮助通知我的内存泄漏.有谁知道什么时候我打电话怎么这么声明这些功能malloc()和free()它会调用我的自定义功能,而不是标准的lib功能?
Ale*_*x B 73
你有几个选择:
GLIBC特定的解决方案(主要是Linux).如果你的编译环境是glibc有gcc,首选方法是使用malloc的钩子.它不仅可以让你指定自定义malloc和free,同时也将通过堆栈上的返回地址识别呼叫方.
POSIX特定的解决方案.定义malloc并free作为可执行文件中原始分配例程的包装,它将"覆盖"libc中的版本.包装里面,你可以调用到原来的malloc实现,你可以看一下使用dlsym与RTLD_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;
}
Run Code Online (Sandbox Code Playgroud)特定于Linux.您可以通过在LD_PRELOAD环境变量中指定动态库来非侵入地覆盖动态库中的函数.
LD_PRELOAD=mymalloc.so ./exe
Run Code Online (Sandbox Code Playgroud)Mac OSX具体.
与Linux相同,除了您将使用DYLD_INSERT_LIBRARIES环境变量.
Grz*_*cki 16
您可以使用LD_PRELOAD执行包装和"覆盖"功能 - 与前面所示的示例类似.
LD_PRELOAD=/path.../lib_fake_malloc.so ./app
Run Code Online (Sandbox Code Playgroud)
但我建议这个"稍微"更聪明,我的意思是调用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;
}
Run Code Online (Sandbox Code Playgroud)
例如我在这里找到的:http://www.jayconrod.com/cgi/view_post.py?23由Jay Conrod发布.
但是我在这个页面上发现非常酷的是:GNU链接器提供了一个有用的选项--wrap.当我检查"man ld"时,有以下示例:
void *
__wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}
Run Code Online (Sandbox Code Playgroud)
我同意他们的"琐碎的例子":).甚至不需要dlsym.
让我,我引用我的"man ld"页面的另一部分:
--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.
Run Code Online (Sandbox Code Playgroud)
我希望,描述完整,并展示如何使用这些东西.
很抱歉重新开放7岁的职位。
就我而言,我需要将memalign / aligned_malloc包装在malloc下。在尝试了其他解决方案之后,我最终实现了下面列出的解决方案。它似乎工作正常。
/*
* 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);
}
Run Code Online (Sandbox Code Playgroud)
在C中,我使用的方法类似于:
#define malloc(x) _my_malloc(x, __FILE__, __LINE__)
#define free(x) _my_free(x)
Run Code Online (Sandbox Code Playgroud)
这使我能够毫不费力地检测分配内存的行和文件.它应该是跨平台的,但如果已经定义了宏,则会遇到问题(如果您使用另一个内存泄漏检测器,则应该是这种情况.)
如果你想在C++中实现相同的,那么这个过程有点复杂,但使用相同的技巧.
这是我多年来使用的一组包装函数(当我浸入C时仍然会这样做)来检测不自由的内存,多次释放内存,引用free'd内存,缓冲区溢出/下溢以及释放内存没有分配.
ftp://ftp.digitalmars.com/ctools.zip
他们已经存在了25年并证明了自己.
您可以使用宏预处理器重新定义malloc并自由使用mem包,但我建议不要使用它,因为它不会将库调用重定向到malloc,就像strdup那样.
如果您为 malloc() 和 free() 定义自己的函数并显式地将其与您的应用程序链接,则应优先使用您的函数而不是库中的函数。
但是,名为“malloc”的函数无法调用库 malloc 函数,因为在“c”中没有单独的命名空间的概念。换句话说,您必须实现 malloc 的内部结构并释放自己。
另一种方法是编写函数 my_malloc() 和 my_free(),它们调用标准库函数。这意味着任何调用 malloc 的代码都必须更改为调用 my_xxx 函数。
| 归档时间: |
|
| 查看次数: |
41218 次 |
| 最近记录: |