c - 为什么 getline 在将 `-wrap=malloc` 传递给链接器时调用 glibc 的 malloc 而不是 __wrap_malloc?

标签 c gcc linker malloc hook

当我尝试将 --wrap=malloc 传递给 ld 链接器以 Hook malloc 时,我发现 getline 不会调用 __wrap_malloc,而是调用glibc的malloc

// foo.c
void* __wrap_malloc(size_t sz) {
   printf("abc");
   return __reall_malloc(sz);
}

int main() {
   char *line = NULL;
   size_t n = 0;
   getline(&line, &n, stdin);   // will call malloc
   ....
}

运行方式: $ gcc foo.c -Wl,--wrap=malloc && ./a.out 它不打印“abc”,似乎 __wrap_malloc 没有被调用。

但运行为: $ gcc -static foo.c -Wl,--wrap=malloc && ./a.out 我有段错误,打印回溯:

#0  0x00000000004490e7 in vfprintf ()
#1  0x0000000000407a76 in printf ()
#2  0x0000000000400ab7 in __wrap_malloc (size=1024) at foo.c:26
#3  0x0000000000456a2b in _IO_file_doallocate ()
#4  0x000000000040d4a5 in _IO_doallocbuf ()
#5  0x000000000040c4d8 in _IO_new_file_overflow ()
#6  0x000000000040b421 in _IO_new_file_xsputn ()
#7  0x000000000044921f in vfprintf ()
#8  0x0000000000407a76 in printf ()
#9  0x0000000000400ab7 in __wrap_malloc (size=1024) at foo.c:26
....

似乎递归调用了__wrap_malloc(最初在printf中调用),也就是说getline调用了__wrap_malloc 而不是 glibc 的 malloc

如果 -static 传递给链接器会发生什么?我如何强制 getline 调用 __wrap_malloc 而不是 glibc 的 malloc

最佳答案

如果 -static 被传递给链接编辑器,链接编辑器可以看到所有对 malloc 的内部调用,并会尝试包装它们,导致无限递归,因为你的自己的 malloc 实现调用 printf,在某些情况下后者又调用 malloc

没有-static,链接编辑器无法重写libc.so.6中的内部malloc引用,所以glibc中的内部调用是从未重定向。没有无限递归,但您也看不到那些内部调用。

glibc 支持使用 ELF 符号插入替换 malloc(只要这样的事情是可能的):

不过,您仍然需要小心避免触发无限递归。

关于c - 为什么 getline 在将 `-wrap=malloc` 传递给链接器时调用 glibc 的 malloc 而不是 __wrap_malloc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57147844/

相关文章:

c++ - 转发声明文件 *

c++ - 无法将右值引用函数与 GCC 匹配

c++ - Win32 应用程序 LNK2001 : unresolved external symbol _main

linux - 为什么 GNU 链接器找不到带有 -l<library> 的共享对象?

c - 来自编程珍珠的最长重复字符串

c - "int a=({10;});"这个表达式用C语言怎么解释?

c - 使用内存地址创建数组时出错

将 SSL 私钥转换为字符串

c++ - 带有 O1、O2 或 O3 的 gcc 4.7.3 创建错误代码

c++ - undefined reference ,但 objdump 显示函数在目标文件中?