c - 可以强制可执行文件使用用户定义的 'malloc' 吗?

标签 c debugging memory-management compilation linker

我想了解内存跟踪器和泄漏检测器是如何工作的,所以我有了这个想法,我有一个可执行文件,我想在执行时强制它使用我自己的内存分配函数而不是通常的系统函数(“malloc", "realloc"...).

我自己的函数存储在一个库(静态的或共享的)或只是一个对象文件(“.o”)中,想想类似的东西:

void *my_own_malloc(unsigned long size) {
     printf("allocate: %lu\n", size);
     return malloc(size);
}

PS:我不用改可执行源码(我没有源码)

PS2:我想在所有不同的平台(Windows、OS X 和 Linux...)上这样做

最佳答案

我不知道其他平台,但在 GNU/Linux 上,您可以使用 LD_PRELOAD 环境变量预加载一个小型内存跟踪库,其中您自己的 mallocfree 被定义。

您自己的 malloc 可能希望使用真正的 malloc 函数分配内存,因此这里可能存在递归问题。为了解决这个问题,dlsym函数可以使用 RTLD_NEXT 参数来获取指向下一个(即“真实”)malloc 函数的指针。

对此的一个非常小的测试可能如下所示:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>

void *malloc(size_t size)
{
    static void *(*real_malloc)(size_t size) = 0;

    if (!real_malloc)
        real_malloc = dlsym(RTLD_NEXT, "malloc");

    void *result = real_malloc(size);
    fprintf(stderr, "malloc(%d) = %p\n", (int)size, result);
    return result;
}

void free(void *ptr)
{
    static void (*real_free)(void *ptr) = 0;
    if (!real_free)
        real_free = dlsym(RTLD_NEXT, "free");

    real_free(ptr);
    fprintf(stderr, "free(%p)\n", ptr);
}

如果我们调用这个文件fakemalloc.c,它可以用命令编译成一个fakemalloc.so共享对象

gcc -fPIC -shared -Wl,-soname,fakemalloc.so -o fakemalloc.so fakemalloc.c -ldl

作为测试,要查看在对 ls 命令的调用中发生了哪些 mallocfree 调用,您需要执行

LD_PRELOAD=/path/to/fakemalloc.so ls

编辑:如评论中所述,在 glibc 系统上,您可以通过使用函数 __libc_malloc 来避免 RTLD_NEXT 方法>__libc_free。这将产生以下代码:

#include <stdio.h>

void *__libc_malloc(size_t size);
void *__libc_free(void *ptr);

void *malloc(size_t size)
{
    void *result = __libc_malloc(size);
    fprintf(stderr, "malloc(%d) = %p\n", (int)size, result);
    return result;
}

void free(void *ptr)
{
    __libc_free(ptr);
    fprintf(stderr, "free(%p)\n", ptr);
}

关于c - 可以强制可执行文件使用用户定义的 'malloc' 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41322044/

相关文章:

OpenGL GPU内存清理,需要吗?

c++ - 调试::gdb::src2dst 是什么?

c# - 内存不足异常,即使有 30 GB 内存可用

c - 给定代码中逻辑错误在哪里?

c - 使用 malloc 创建指向指针的指针数组时出现段错误

java - 如何在 NetBeans 的 Debug模式下进入已实现的方法?

python - 查找数组是否包含 2 旁边的 2

c - *** 检测到 glibc *** ./m : free(): invalid next size (fast) on trying to free heap memory

c - 将参数传递给 argv 指针的最短方法

c - % 和/in C 有什么区别?