繁体   English   中英

LD_PRELOAD只适用于malloc,而不是免费的

[英]LD_PRELOAD only working for malloc, not free

我试图通过LD_PRELOAD设置malloc / free / calloc / realloc等与一些插入器。 在我的小测试中,只有malloc似乎插入,即使检测到free (参见输出)。

我希望输出包含一行“NANO:free(x)” - 但这行不见了。

特定

// compile with: gcc test.cc
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {

    void* p = malloc(123);
    printf("HOST p=%p\n", p);
    free(p);
}

// compile with:  g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared main.cc
#include <stdio.h>
#include <dlfcn.h>

typedef void *(*MallocFunc)(size_t size);
typedef void (*FreeFunc)(void*);

// Original functions
static MallocFunc real_malloc = NULL;
static FreeFunc real_free = NULL;

static void __nano_init(void) {
    // Override original functions
    real_malloc = (MallocFunc)dlsym(RTLD_NEXT, "malloc");
    if (NULL == real_malloc) {
        fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
    } else {
        fprintf(stderr, "NANO: malloc() replaced @%p\n", real_malloc);
    }

    real_free = (FreeFunc)dlsym(RTLD_NEXT, "free");
    if (NULL == real_free) {
       fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
    } else {
        fprintf(stderr, "NANO: free() replaced @%p\n", real_free);
    }
}

// replacement functions
void *malloc(size_t size) {
    if(real_malloc==NULL) __nano_init();

    void *p = NULL;
    fprintf(stderr, "NANO: malloc(%lu) = ", size);
    p = real_malloc(size);
    fprintf(stderr, "%p\n", p);

    return p;
}

void free(void* ptr) {
    if(real_free==NULL) __nano_init();

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

    return;
}

实际输出是:

% ./a.out
NANO: malloc() replaced @0x3b36274dc0
NANO: free() replaced @0x3b36272870
NANO: malloc(123) = 0x601010
HOST p=0x601010

你正在编译一个C ++; 这意味着(默认情况下)函数被命名为适合C ++ ABI。 不幸的是,您尝试挂钩的函数没有名称错误,因此您最终会挂错(不存在)函数。

解决方法是:a)在extern "C" { }块中定义包装器或a)确保包含函数的头 - 如#include <cstdlib> 这将使用extern "C"包装器引入mallocfree声明,告诉编译器不要命名。

malloc工作的原因可能是因为<stdio.h><dlfcn.h>malloc的声明但不是 free 因此, malloc是不受限制的,但是free被破坏了。

另请注意:如果您正在使用glibc,则应使用malloc挂钩来挂钩内存分配函数。 glibc使用符号版本控制做一些非常奇怪的事情,否则可能会干扰你的钩子。 如何使用它的一个例子是链接的文档 - 如果你正在使用C ++,不要忘记extern "C"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM