我想将 malloc
包装在一个函数中,该函数将打印分配大小、指针地址和分配时间。这可以通过我的 malloc
实现预加载我的共享库来实现。这段代码实现了:
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
static void* (*real_malloc)(size_t size) = NULL;
static void* (*real_calloc)(size_t nelements, size_t elementSize) = NULL;
static void init(void)
{
real_malloc = dlsym(RTLD_NEXT, "malloc");
if (NULL == real_malloc)
{
fprintf(stderr, "Error: %s\n", dlerror());
}
}
void *malloc(size_t size)
{
if(real_malloc == NULL)
{
init();
}
void *p = NULL;
p = real_malloc(size);
fprintf(stderr, "size=%lu, pointer=%p\n", size, p);
return p;
}
但是如果我将时间打印功能添加到 malloc
中:
static void printTime()
{
time_t timer;
char buffer[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
fprintf(stderr, "%s\n", buffer);
}
并添加 time.h
header 并使用可执行文件运行我的 .so 库,它将简单地卡住并且不执行任何操作。
我怀疑 time
或 localtime
在幕后调用 malloc
并以某种方式导致问题。另一方面,real_malloc
确实被调用,所以应该不会有问题。
我的可执行文件是多线程的,但添加互斥体没有帮助。我编译.so的方式如下:
gcc -fPIC -shared -o bin/libpreload.so myAlloc.c -ldl
可以使用 Linux ps
程序验证该问题:
cd/bin && LD_PRELOAD=/home/用户名/Desktop/alloc/bin/libpreload.so ./ps
最佳答案
如果 malloc
中的日志记录函数最终调用 malloc
,您需要跳出递归循环。
因此,仅当在日志记录之外调用 malloc 时才进行日志记录。
void *malloc(size_t size)
{
if(real_malloc == NULL)
{
init();
}
void *p = NULL;
p = real_malloc(size);
if (do_logging)
{
do_logging = 0;
fprintf(stderr, "size=%lu, pointer=%p\n", size, p);
printTime();
do_logging = 1;
}
return p;
}
当然,如果您希望它在多线程程序中工作,您必须将 do_logging
放入线程本地存储中。在 c11 及更高版本中,您可以这样做:
#include <threads.h>
thread_local int do_logging = 1;
哦,你的 init
函数可能不是线程安全的。
关于c - 如何预加载共享库并使用在同一包装函数中使用 malloc 的函数来包装 malloc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56176875/