当我使用LD_PRELOAD=/usr/local/lib/libtcmalloc.so
时,我对malloc的所有调用都成为tcmalloc调用。但是,当我静静地链接到libtcmalloc时,我发现直接malloc被调用,除非我仍然使用LD_PRELOAD
设置。
那么我怎样才能以某种方式对tcmalloc进行静态编译,使我的mallocs挂钩到tcmalloc?
注意:
答案 0 :(得分:12)
符号在第一场比赛的基础上得到解决。您需要确保链接器在 libc.a之前搜索 libtcmalloc.a。我假设你没有明确地链接libc.a,因为你通常不需要这样做。解决方案是指定-nostdlibs,然后按照您希望它们搜索的顺序显式链接所有必需的库。通常类似于:
-nostdlibs -llibtcmalloc -llibm -llibc -llibgcc
另一个可能更简单的解决方案是链接解析tcmalloc而不是静态库所需的目标文件,因为在解析符号时,目标文件优先于库。
答案 1 :(得分:1)
TCMalloc会覆盖所有分配/释放函数调用,包括 New / Delete 和C API( malloc / )的所有变体自由 / 释放calloc / 的realloc / valloc / pvalloc / mem_aligned / malloc_usable_size ) 对于基于gcc的平台,它使用别名指令实现覆盖。
我正在使用大量的C ++ new等,所以#defining malloc to tcmalloc将无法正常工作
在TCMalloc标头中, malloc 已经别名为 tc_malloc ,因此无效。例如:
#define ALIAS(tc_fn) __attribute__ ((alias (#tc_fn), used))
void* malloc(size_t size) __THROW ALIAS(tc_malloc)
至于 New ,请注意,与glibc和 New (windows)的其他实现不同,那只是包装malloc,tcmalloc的New不会调用malloc。
TCMalloc 新别名为 tc_new 和 tc_newarray ,它将调用TCMalloc的“神奇”内存管理器,在某些情况下,作为libc malloc,将启动一个sbrk / brk系统调用。
您需要做的另一件事是确保gcc不与libc的malloc变体链接。为此,请在Makefile中添加以下C ++ Flags:
-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free
另外,不要忘记指定TCMalloc静态库:
LIB_TCMALLOC = $(TCMALLOC_LIB_DIR)/libtcmalloc_minimal.a
LIB_DIR := .... -L$(TCMALLOC_LIB_DIR) ...
LIBS := ... -static $(LIB_TCMALLOC) ...
我可能必须自己使用malloc_hook,但我原本以为我可以让tcmalloc为我做这件事,因为它在动态链接时显然是这样做的
TCMalloc不使用malloc_hooks,由于线程安全问题,现在认为它已被弃用。它只是使用内存分配方法是弱符号的事实。它使用函数调用的别名(在gcc中)__attribute__((alias))
来覆盖这些符号。
请参阅: https://github.com/gperftools/gperftools/blob/master/README