【发布时间】:2017-02-20 04:37:23
【问题描述】:
我正在使用 LD_PRELOAD 记录来自应用程序的 malloc 调用并映射出虚拟地址空间,但是 malloc 在 fopen/printf 内部使用。有没有办法解决这个问题?
我知道 glibc 的钩子,但我想避免更改应用程序的源代码。
【问题讨论】:
-
请定义您遇到的问题。描述没有说明递归。
标签: c++ c ld-preload
我正在使用 LD_PRELOAD 记录来自应用程序的 malloc 调用并映射出虚拟地址空间,但是 malloc 在 fopen/printf 内部使用。有没有办法解决这个问题?
我知道 glibc 的钩子,但我想避免更改应用程序的源代码。
【问题讨论】:
标签: c++ c ld-preload
我的问题是由 glibc 在内部使用 malloc 引起的,所以当我使用 LD_PRELOAD 覆盖 malloc 时,任何记录尝试都会导致 malloc 被调用,从而导致对 malloc 本身的递归调用
解决方案: 每当 TLS 需要内存分配时调用原始 malloc 提供代码:
static __thread int no_hook;
static void *(*real_malloc)(size_t) = NULL;
static void __attribute__((constructor))init(void) {
real_malloc = (void * (*)(size_t))dlsym(RTLD_NEXT, "malloc");
}
void * malloc(size_t len) {
void* ret;
void* caller;
if (no_hook) {
return (*real_malloc)(len);
}
no_hook = 1;
caller = (void*)(long) __builtin_return_address(0);
printf("malloc call %zu from %lu\n", len, (long)caller);
ret = (*real_malloc)(len);
// fprintf(logfp, ") -> %pn", ret);
no_hook = 0;
return ret;
}
【讨论】:
init() 之前调用 -fsanitizer=address 编译器参数 malloc()。因此,将检查:if (!real_malloc) init(); 添加到自定义 malloc。