tcmalloc和glibc

时间:2018-06-15 11:25:20

标签: 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}, *res = NULL;
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        int rc = getaddrinfo("myserver", NULL, &hints, &res);
        assert(rc == 0);
        return 0;
}

我使用以下命令编译它:

  

g ++ temp.cpp -g -lresolv

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

  

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

程序崩溃时出现以下堆栈:

  

#0 0x00007ffff6c7c875 in * __ GI_raise(sig =)at ../ nptl / sysdeps / unix / sysv / linux / raise.c:64

     

#1 0x00007ffff6c7de51 in * __ GI_abort()at abort.c:92

     

#2 0x00007ffff6cbd8bf in __libc_message(do_abort = 2,fmt = 0x7ffff6d8c460&#34; *** glibc检测到***%s:%s:0x%s *** \ n&#34;)at ../ sysdeps / UNIX / SYSV / LINUX / libc_fatal.c:186

     malloc_printerr中的

#3 0x00007ffff6cc30c8(action = 2,str = 0x7ffff6d88fec&#34; free():无效指针&#34;,ptr =)at malloc.c:6282

     

#4 0x00007ffff6cc810c in * __ GI___libc_free(mem =)at malloc.c:3733

     

#5 0x00007ffff6839e89 in _nss_dns_gethostbyname4_r(name = 0x400814&#34; myserver&#34;,pat = 0x7fffffffdfa8,buffer = 0x7fffffffd9b0&#34; myserver.mydomain.com&#34;,buflen = 1024,errnop = 0x7fffffffdfbc,herrnop = 0x7fffffffdf98,ttlp = 0x0)在nss_dns / dns-host.c:341

     

#6 0x00007ffff6d11917在gaih_inet(名称= 0x400814&#34; myserver&#34;,服务= 0x7fffffffdf88,req = 0x7fffffffe1d0,pai = 0x7fffffffe160,naddrs = 0x7fffffffe168)at ../sysdeps/posix/getaddrinfo.c:880

     

#7 0x00007ffff6d14301 in * __ GI_getaddrinfo(name = 0x400814&#34; myserver&#34;,service = 0x0,hints = 0x7fffffffe1d0,pai = 0x7fffffffe200)at ../sysdeps/posix/getaddrinfo.c:2452

     

#8 0x00000000004006f0 in main()at temp.cpp:12

原因是来自free()的{​​{1}}调用的_nss_dns_gethostbyname4_r()函数来自libnss_dns.solibc.so来自malloc()来自libresolv.so。 tcmalloc的libtcmalloc_minimal.somalloc()函数的地址正在进入导致此崩溃的free()的GOT。如果我不将我的程序链接到libresolv.so,那么崩溃就会消失。

现在提出我的问题。是否有任何文档解释如何安全地使用tcmalloc来避免这样的崩溃?

1 个答案:

答案 0 :(得分:1)

glibc有一些插入Film的文档:

但是,其他必须要去的地方。 glibc和glibc的典型构建将做到这一点(即使在任何一个软件包的相当旧的版本中)。

我最好的猜测是你正在使用一些SUSE glibc变体which uses RTLD_DEEPBIND for NSS modules。这导致known issue with malloc interposition。 SUSE建议setting the RTLD_DEEPBIND=0 environment variable作为解决方法。