LD_PRELOAD 仅适用于 malloc,不适用于 free
我正在尝试通过 LD_PRELOAD 使用一些插入器插入 malloc/free/calloc/realloc 等。在我的小测试中,即使检测到 free
(请参阅输出),似乎也只插入了 malloc
。
我希望输出包含一行“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);
}
And
// 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
I'm trying to interpose malloc/free/calloc/realloc etc with some interposers via LD_PRELOAD. In my small test, only malloc
seems to be interposed, even though free
is detected (see output).
I'd expect the output to contain a line "NANO: free(x)" - but this line is missing.
Given
// 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);
}
And
// 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;
}
The actual output is:
% ./a.out
NANO: malloc() replaced @0x3b36274dc0
NANO: free() replaced @0x3b36272870
NANO: malloc(123) = 0x601010
HOST p=0x601010
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你正在编译一个C++;这意味着(默认情况下)函数会被名称修改以适应 C++ ABI。不幸的是,您尝试挂钩的函数没有名称损坏,因此您最终会挂钩错误的(不存在的)函数。
解决方法是 a) 在
extern "C" { }
块中定义包装器,或者 a) 确保包含函数的标头 - 如#include中所示
。这将使用extern "C"
包装器引入malloc
和free
声明,告诉编译器不要进行名称修改。malloc
起作用的原因可能是因为
或
引入了malloc 的声明
但不是免费
。因此,malloc
未损坏,但free
已损坏。另请注意:如果您使用 glibc,则应该使用 malloc hooks 挂钩内存分配函数。 glibc 在符号版本控制方面做了一些非常奇怪的事情,否则可能会干扰你的钩子。如何使用它的示例位于链接的文档中 - 不过,如果您使用的是 C++,请不要忘记
extern "C"
!You are compiling a C++; this means that (by default) functions are name-mangled to fit the C++ ABI. Unfortunately, the functions you are trying to hook are not name-mangled, so you end up hooking the wrong (nonexistent) function.
The fix is to either a) define your wrappers in a
extern "C" { }
block or a) make sure you include the header for the function - as in#include <cstdlib>
. This will pull in declarations formalloc
andfree
with anextern "C"
wrapper, telling the compiler not to name-mangle.The reason
malloc
works is probably because<stdio.h>
or<dlfcn.h>
pulls in a declaration formalloc
but notfree
. Thus,malloc
is unmangled, butfree
is mangled.Also note: If you're using glibc, you should be using malloc hooks to hook memory allocation functions. glibc does some pretty weird stuff with symbol versioning that may interfere with your hooks otherwise. An example of how to use it is in the documentation linked - don't forget
extern "C"
s if you're using C++, though!