C++插桩

ubuntu c++下 我想利用插桩的方式使函数在申请内存时,打印其所在文件和行数

要在 Ubuntu 下利用插桩的方式,使函数在申请内存时打印其所在文件和行数,你可以使用以下方法:

方法:使用 LD_PRELOAD 和 backtrace 功能
我们可以利用 LD_PRELOAD 环境变量来插入自定义的 malloc、calloc、realloc 和 free 函数。在这些自定义函数中,我们可以使用 backtrace 和 backtrace_symbols 来获取调用栈信息,进而打印内存分配所在的文件和行数。

以下是具体步骤:

创建一个共享库文件 my_malloc_logger.cpp:
cpp
复制代码
#include <cstdio>
#include <cstdlib>
#include <dlfcn.h>
#include <execinfo.h>

void* (*real_malloc)(size_t) = nullptr;
void* (*real_calloc)(size_t, size_t) = nullptr;
void* (*real_realloc)(void*, size_t) = nullptr;
void (*real_free)(void*) = nullptr;

void print_backtrace() {
    const int max_frames = 10;
    void* buffer[max_frames];
    int num_frames = backtrace(buffer, max_frames);
    char** symbols = backtrace_symbols(buffer, num_frames);
    
    for (int i = 0; i < num_frames; ++i) {
        printf("%s\n", symbols[i]);
    }
    
    free(symbols);
}

extern "C" void* malloc(size_t size) {
    if (!real_malloc) {
        real_malloc = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc");
    }
    void* result = real_malloc(size);
    printf("malloc(%zu) = %p\n", size, result);
    print_backtrace();
    return result;
}

extern "C" void* calloc(size_t num, size_t size) {
    if (!real_calloc) {
        real_calloc = (void* (*)(size_t, size_t))dlsym(RTLD_NEXT, "calloc");
    }
    void* result = real_calloc(num, size);
    printf("calloc(%zu, %zu) = %p\n", num, size, result);
    print_backtrace();
    return result;
}

extern "C" void* realloc(void* ptr, size_t size) {
    if (!real_realloc) {
        real_realloc = (void* (*)(void*, size_t))dlsym(RTLD_NEXT, "realloc");
    }
    void* result = real_realloc(ptr, size);
    printf("realloc(%p, %zu) = %p\n", ptr, size, result);
    print_backtrace();
    return result;
}

extern "C" void free(void* ptr) {
    if (!real_free) {
        real_free = (void (*)(void*))dlsym(RTLD_NEXT, "free");
    }
    printf("free(%p)\n", ptr);
    real_free(ptr);
}
编译共享库:
bash
复制代码
g++ -shared -fPIC -o my_malloc_logger.so my_malloc_logger.cpp -ldl -rdynamic
运行你的程序并使用 LD_PRELOAD 插入共享库:
bash
复制代码
LD_PRELOAD=./my_malloc_logger.so ./your_program
通过这种方式,当程序调用 malloc、calloc、realloc 或 free 时,会打印出内存分配的大小、返回的指针以及调用栈信息。调用栈信息可以帮助你找出内存分配所在的文件和行数。

解释
dlsym:用于查找动态链接库中的符号。在这里,我们使用它来查找实际的内存分配函数(如 malloc、calloc、realloc 和 free)。
backtrace 和 backtrace_symbols:用于获取和打印调用栈信息。backtrace 获取调用栈中的地址,backtrace_symbols 将这些地址转换为可读的符号信息。
LD_PRELOAD:环境变量,用于在程序启动时加载指定的共享库,从而可以重载特定的函数。
这样,你可以在程序运行时跟踪到所有的内存分配调用及其所在的文件和行数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值