What steps will reproduce the problem?
1. Run program to profile
LD_PRELOAD=/opt/google-perftools/lib/libtcmalloc.so.0
HEAPPROFILE=/root/myprog.hprof HEAP_PROFILE_MMAP=true
HEAP_PROFILE_MMAP_LOG=true myprog
2. It writes to output and locks.
Starting tracking the heap
mmap(start=0x0, len=69632, prot=0x3, flags=0x22, fd=-1, offset=0x0) =
0x2aaab08b8000
What is the expected output? What do you see instead?
What version of the product are you using? On what operating system?
google-perftools-0.91 compiled from sources with gcc-3.2 on FC6 x86_64
arch.
Please provide any additional information below.
The first deadlock appeared when heap profiler calls HeapProfilerStart
from HeapProfilerInit with initialized mmap hooks and heap_lock held.
After I moved mmap hooks initialization to the end of HeapProfilerInit:
HeapProfileTable::CleanupOldProfiles(fname);
HeapProfilerStart(fname);
if (FLAGS_mmap_profile || FLAGS_mmap_log) {
MallocHook::SetMmapHook(MmapHook);
MallocHook::SetMunmapHook(MunmapHook);
}
Second deadlock appeared with following call stack (some functions seems
to be inlined, though I compiled all programs with -g and without any -O
flags):
#0 0x00000034da98f7a2 in __nanosleep_nocancel ()
from /lib64/tls/libc.so.6
#1 0x00002aaaaaafd57a in
HeapLeakCheckerGlobalPrePost::~HeapLeakCheckerGlobalPrePost () at
src/malloc_hook.cc:294
#2 0x00002aaaaaadc263 in SpinLock::Lock (this=0x2aaaaad2dac0) at
VZLCounter.h:129
#3 0x00002aaaaaae7dc2 in RecordAlloc (ptr=0x2aaab08b8000, bytes=69632,
skip_count=0) at src/heap-profiler.cc:195
#4 0x00002aaaaaae803a in MmapHook (result=0x2aaab08b8000, start=0x0,
size=69632, prot=3, flags=34, fd=-1, offset=0)
at src/heap-profiler.cc:267
#5 0x00002aaaaaae208d in MallocHook::InvokeMmapHook
(result=0x2aaab08b8000, start=0x0, size=69632, protection=3, flags=34,
fd=-1, offset=0) at src/google/malloc_hook.h:100
#6 0x00002aaaaaafe141 in virtual thunk to
VZL::VZLForkableRefCounter::~VZLForkableRefCounter$delete() () at
VZLCounter.h:129
#7 0x00002aaaaaafe5e0 in LowLevelAlloc::Alloc (request=65560,
arena=0x2aaaadf30020) at VZLCounter.h:129
#8 0x00002aaaaaae7bb8 in ProfilerMalloc (bytes=65560) at
src/heap-profiler.cc:110
#9 0x00002aaaaaaea5c9 in MallocHook::SetDeleteHook () at
src/heap-checker.cc:367
#10 0x00002aaaaaaea319 in MallocHook::SetDeleteHook () at
src/heap-checker.cc:367
#11 0x00002aaaaaae9cd0 in MallocHook::SetDeleteHook ()
at /usr/include/c++/3.2.3/bits/basic_string.h:955
#12 0x00002aaaaaae913a in MallocHook::SetDeleteHook ()
at /usr/include/c++/3.2.3/bits/basic_string.h:955
#13 0x00002aaaaaae7de8 in RecordAlloc (ptr=0x1c7021d8, bytes=1,
skip_count=0) at src/heap-profiler.cc:197
#14 0x00002aaaaaae7f4f in NewHook (ptr=0x1c7021d8, size=1) at
src/heap-profiler.cc:240
#15 0x00002aaaaaae0e11 in MallocHook::InvokeNewHook (p=0x1c7021d8, s=1)
at src/google/malloc_hook.h:62
#16 0x00002aaaaaafd8be in malloc (size=1) at src/tcmalloc.cc:2785
#17 0x00002aaaaaae1323 in TCMallocGuard (this=0x2aaaaad2d860) at
src/tcmalloc.cc:2510
#18 0x00002aaaaaae00cc in __static_initialization_and_destruction_0
(__initialize_p=1, __priority=65535) at src/tcmalloc.cc:2525
#19 0x00002aaaaaae07f9 in global constructors keyed to
_ZN61FLAG__namespace_do_not_use_directly_use_DECLARE_int64_instead31FLAGS_tcmall
oc_sample_parameterE
() at src/tcmalloc.cc:572
#20 0x00002aaaaaafd886 in
HeapLeakCheckerGlobalPrePost::~HeapLeakCheckerGlobalPrePost () at
src/malloc_hook.cc:294
I suppose RecordAlloc should be reentrant or there should be some flag to
suspend tcmalloc's allocation logging.