【问题标题】:Why does the getline call glibc's malloc instead of __wrap_malloc when passing `-wrap=malloc` to the linker?为什么 getline 在将 `-wrap=malloc` 传递给链接器时调用 glibc 的 malloc 而不是 __wrap_malloc?
【发布时间】:2019-11-30 12:53:32
【问题描述】:

当我尝试将--wrap=malloc 传递给ld 链接器以挂钩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

【问题讨论】:

  • 从条目 10 到 main 的堆栈回溯中有什么?由于printf() 调用malloc(),您已经创建了递归,这可能不会导致幸福?您的 __wrap_malloc() 最终在 printf() 完成之前被调用 - 并且在它 (__wrap_malloc) 分配内存之前。尝试将printf() 替换为write(2, "abc\n", 4);,然后看看世界是否变得更加阳光充足。
  • @KamilCuk 我想保留 glibc 的 malloc 和我的自定义 malloc。修改__malloc_hook指针或覆盖弱符号(如malloc_usable_size)会丢失glibc的malloc(或malloc_usable_size)。我怎样才能保留他们两个?谢谢!

标签: c gcc linker malloc hook


【解决方案1】:

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

没有-static,链接编辑器无法重写libc.so.6 中的内部malloc 引用,因此glibc 中的内部调用永远不会重定向。没有无限递归,但你也看不到那些内部调用。

glibc 支持使用 ELF 符号插入替换 malloc(只要有可能):

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

【讨论】:

  • 我试过这个方法replacing_malloc。但是,我想要的是 glibc 的 malloc 和我的自定义 malloc 在链接后都被保留。修改__malloc_hook指针或覆盖弱符号(如malloc_usable_size)会丢失glibc的malloc。我怎样才能保留他们两个?谢谢!
猜你喜欢
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2011-09-18
相关资源
最近更新 更多