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:环境变量,用于在程序启动时加载指定的共享库,从而可以重载特定的函数。 这样,你可以在程序运行时跟踪到所有的内存分配调用及其所在的文件和行数。
C++插桩
最新推荐文章于 2024-09-13 17:43:09 发布