tcmalloc和glibc暴露的符号冲突

tcmalloc和glibc暴露的符号冲突,glibc,tcmalloc,Glibc,Tcmalloc,我最近在调试一个产品中的崩溃,并确定原因是glibc和tcmalloc公开的内存分配符号冲突。我编写了以下示例代码来公开此问题: #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <assert.h> #include <stdlib.h> int main() { struct addrinfo hints = {0}

我最近在调试一个产品中的崩溃,并确定原因是glibc和tcmalloc公开的内存分配符号冲突。我编写了以下示例代码来公开此问题:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <assert.h>
#include <stdlib.h>

int main()
{
        struct addrinfo hints = {0}, *res = NULL;
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        int rc = getaddrinfo("myserver", NULL, &hints, &res);
        assert(rc == 0);
        return 0;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
struct addrinfo hints={0},*res=NULL;
hits.ai_family=AF_unsec;
hits.ai_socktype=SOCK_流;
int rc=getaddrinfo(“myserver”,NULL,&hints,&res);
断言(rc==0);
返回0;
}
我使用以下命令编译了它:

g++temp.cpp-g-lresolv

我使用以下命令执行程序:

LD_PRELOAD=/path/to/libtcmalloc_minimal.so.4./a.out

程序因以下堆栈而崩溃:

#在../nptl/sysdeps/unix/sysv/linux/raise.c:64处0 0x00007ffff6c7c875 in*u GI_raise(sig=)中

#1 0x00007FF6C7DE51位于abort处的*u_GI_abort()中。c:92

#在../sysdeps/unix/sysv/linux/libc\u fatal.c:186处的消息(do_abort=2,fmt=0x7ffff6d8c460“***glibc检测到***%s:%s:0x%s***\n)中有2 0x00007FF6CBD8BF

#3 malloc_printerr中的0x00007ffff6cc30c8(action=2,str=0x7ffff6d88fec“free():无效指针”,ptr=)位于malloc.c:6282

#4 0x00007ffff6cc810c在malloc的*.\uuuuu GI.\uuuuu libc_free(mem=)中。c:3733

#5 0x00007ffff6839e89在nss\U dns\U gethostbyname4\u r(name=0x400814“myserver”,pat=0x7fffffffdfa8,buffer=0x7fffffffd9b0“myserver.mydomain.com”,buflen=1024,errnop=0x7fffffffdfbc,herrnop=0x7fffffffffdf98,ttlp=0x0)在nss\U dns/dns主机上。c:341

#6 0x00007ffff6d11917,位于../sysdeps/posix/getaddrinfo.c:880的gaih_inet(名称=0x400814“myserver”,服务=0x7fffffffdf88,请求=0x7FFFFFFFFFE1D0,pai=0x7fffffffe160,naddrs=0x7fffffffe168)中

#7 0x00007ffff6d14301位于../sysdeps/posix/getaddrinfo.c:2452的*uu_GI_getaddrinfo中(名称=0x400814“myserver”,服务=0x0,提示=0x7fffffffe1d0,pai=0x7fffffffe200)

#温度cpp:12时,主管道()中的8 0x00000000004006f0

这是因为
libnss\u dns\u gethostbyname4\u r()
libnss\u dns调用的
free()
函数是从
libc.so
调用的,而相应的
malloc()
是从
libresolv.so
libtcmalloc.so
调用的。tcmalloc的
malloc()
free()
函数的地址正在进入
libresolv的目录中。因此
导致了这次崩溃。如果我不将程序链接到
libresolv.so
,崩溃就会消失


现在回答我的问题。是否有任何文档说明如何安全地使用tcmalloc来避免类似的崩溃?

glibc有一些文档说明如何插入
malloc

不过,这里肯定还有别的事情。glibc和glibc的典型构建将正确地实现这一点(即使在这两个包的相当旧的版本中)


我最好的猜测是你正在使用一些SUSE-glibc变体。这导致了一个新的问题。SUSE建议作为解决办法。

谢谢你的指点!我确实在测试SuSE(SLES11SP4),在设置环境变量后没有发生崩溃。我没想到glibc会是罪魁祸首,我希望tcmalloc会为此提供一些文档。如果我没有得到关于这个问题的tcmalloc文档的指针(正如我在上面的问题中所问的),我将接受这个答案。