使用tcmalloc编译启动时宕机
链接时增加了-ltcmalloc,编好之后服务器第一次启动就宕机了,code文件堆栈如下:
Program terminated with signal SIGABRT, Aborted. #0 0x0000000000bdfda8 in raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x0000000000bdfda8 in raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x0000000000b63538 in abort () at abort.c:89 #2 0x0000000000b58487 in uw_init_context_1 (context=context@entry=0x7ffeeca2b170, outer_cfa=outer_cfa@entry=0x7ffeeca2b420, outer_ra=0xaa23da <GetStackTrace_libgcc(void**, int, int)+42>) at ../../../gcc-5.1.0/libgcc/unwind-dw2.c:1563 #3 0x0000000000b59048 in _Unwind_Backtrace (trace=0xaa25c0 <libgcc_backtrace_helper(_Unwind_Context*, void*)>, trace_argument=0x7ffeeca2b420) at ../../../gcc-5.1.0/libgcc/unwind.inc:283 #4 0x0000000000aa23da in GetStackTrace_libgcc (result=<optimized out>, max_depth=<optimized out>, skip_count=<optimized out>) at src/stacktrace_libgcc-inl.h:100 #5 0x0000000000aa2ab4 in GetStackTrace (result=result@entry=0x2f3d250, max_depth=max_depth@entry=30, skip_count=skip_count@entry=3) at src/stacktrace.cc:295 #6 0x0000000000a9f256 in tcmalloc::RecordGrowth (growth=1048576) at src/page_heap.cc:618 #7 tcmalloc::PageHeap::GrowHeap (this=0x1757a80 <tcmalloc::Static::pageheap_>, n=<optimized out>) at src/page_heap.cc:644 #8 0x0000000000a9f553 in tcmalloc::PageHeap::New (this=0x1757a80 <tcmalloc::Static::pageheap_>, n=n@entry=1) at src/page_heap.cc:154 #9 0x0000000000a99075 in tcmalloc::CentralFreeList::Populate (this=this@entry=0x18dbf00 <tcmalloc::Static::central_cache_+4864>) at src/central_freelist.cc:329 #10 0x0000000000a99278 in tcmalloc::CentralFreeList::FetchFromOneSpansSafe (this=0x18dbf00 <tcmalloc::Static::central_cache_+4864>, N=1, start=0x7ffeeca2b5c0, end=0x7ffeeca2b5c8) at src/central_freelist.cc:284 #11 0x0000000000a99304 in tcmalloc::CentralFreeList::RemoveRange (this=0x18dbf00 <tcmalloc::Static::central_cache_+4864>, start=start@entry=0x7ffeeca2b5c0, end=end@entry=0x7ffeeca2b5c8, N=1) at src/central_freelist.cc:264 #12 0x0000000000aa1110 in tcmalloc::ThreadCache::FetchFromCentralCache (this=this@entry=0x2f7d240, cl=cl@entry=4, byte_size=byte_size@entry=48, oom_handler=oom_handler@entry=0xa953d0 <(anonymous namespace)::nop_oom_handler(size_t)>) at src/thread_cache.cc:126 #13 0x0000000000c2870b in tcmalloc::ThreadCache::Allocate (oom_handler=0xa953d0 <(anonymous namespace)::nop_oom_handler(size_t)>, cl=4, size=48, this=<optimized out>) at src/thread_cache.h:380 #14 (anonymous namespace)::do_malloc (size=48) at src/tcmalloc.cc:1367 #15 tcmalloc::do_allocate_full<tcmalloc::malloc_oom> (size=48) at src/tcmalloc.cc:1758 #16 tcmalloc::allocate_full_malloc_oom (size=size@entry=48) at src/tcmalloc.cc:1774 #17 0x0000000000c28876 in tcmalloc::dispatch_allocate_full<tcmalloc::malloc_oom> (size=48) at src/tcmalloc.cc:1787 #18 malloc_fast_path<tcmalloc::malloc_oom> (size=size@entry=48) at src/tcmalloc.cc:1852 #19 tc_malloc (size=size@entry=48) at src/tcmalloc.cc:1880 #20 0x0000000000c1cccb in _dl_get_origin () at ../sysdeps/unix/sysv/linux/dl-origin.c:50 #21 0x0000000000bd58ff in _dl_non_dynamic_init () at dl-support.c:314 #22 0x0000000000bd6a08 in __libc_init_first (argc=argc@entry=4, argv=argv@entry=0x7ffeeca2c7b8, envp=0x7ffeeca2c7e0) at ../csu/init-first.c:79 #23 0x0000000000b5b23d in __libc_start_main (main=0x41d6dc <main(int, char**)>, argc=4, argv=0x7ffeeca2c7b8, init=0xb5b6c0 <__libc_csu_init>, fini=0xb5b750 <__libc_csu_fini>, rtld_fini=0x0, stack_end=0x7ffeeca2c7a8) at libc-start.c:224 #24 0x0000000000400c1d in _start () (gdb)
因为tcmalloc的静态库文件是自己编译的,有源码,于是乎就开始纠结地看起了源码。看了很久源码并且尝试调试,都没有什么进展。看堆栈提到了_Unwind_Backtrace,并且想起来在编译的时候,看到过关于unwind的相关警告:
$ ./configure
... ...
configure: WARNING: No frame pointers and no libunwind. Using experimental backtrace capturing via libgcc. Expect crashy cpu profiler.
查看源码目录下的INSTALL文件(我的 gperftools 版本是2.7),查看到如下说明:
重新编译:
$ ./configure --enable-frame-pointers ... ... configure: creating ./config.status config.status: creating Makefile config.status: creating src/gperftools/tcmalloc.h config.status: creating src/windows/gperftools/tcmalloc.h config.status: creating src/config.h config.status: src/config.h is unchanged config.status: executing depfiles commands config.status: executing libtool commands $ make
果然没有警告了,然后拷贝.libs目录下的 libtcmalloc.a 到静态编译目录,重新编译服务器,再次开启,果然没有报错了。