theRockLiu / gperftools

Automatically exported from code.google.com/p/gperftools
BSD 3-Clause "New" or "Revised" License
1 stars 0 forks source link

SEGV when export MALLOCSTATS= + valgrind #536

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. export MALLOCSTATS=2 (or 1)
2. run an app using tcmalloc under valgrind
3. a SEGV is raised

What is the expected output? What do you see instead?
No SEGV. 

What version of the product are you using? On what operating system?
2.0 on linux

Please provide any additional information below.
This reports a minor bug in tcmalloc.

tcmalloc contains specific code allowing an application with tcmalloc to
run properly under Valgrind.

However, when running under valgrind with export MALLOCSTATS=2 (or 1) a
segmentation violation is raised such as:

==8296== Invalid read of size 4
==8296==    at 0x860DCE7: tcmalloc::PageHeap::stats() const
(page_heap.h:150)
==8296==    by 0x860BAE1: ExtractStats(TCMallocStats*, unsigned long
long*, tcmalloc::PageHeap::SmallSpanStats*,
tcmalloc::PageHeap::LargeSpanStats*) (tcmalloc.cc:337)
==8296==    by 0x860BDA4: DumpStats(TCMalloc_Printer*, int)
(tcmalloc.cc:358)
==8296==    by 0x860C8D8: PrintStats(int) (tcmalloc.cc:483)
==8296==    by 0x860D75C: TCMallocGuard::~TCMallocGuard()
(tcmalloc.cc:915)
==8296==    by 0x860D771: __tcf_0 (tcmalloc.cc:920)
==8296==    by 0x40E2DA8: exit (in /lib/libc-2.5.so)
==8296==    by 0x40CCEA3: (below main) (in /lib/libc-2.5.so)
==8296==  Address 0x218b4 is not stack'd, malloc'd or (recently) free'd
==8296== 

I believe the above can be avoided by changing
TCMallocGuard::~TCMallocGuard() {
  if (--tcmallocguard_refcount == 0) {
    const char* env = getenv("MALLOCSTATS");
    if (env != NULL) {
      int level = atoi(env);
      if (level < 1) level = 1;
      PrintStats(level);
    }
  }
}

to avoid calling PrintStats when running under Valgrind, i.e.:
  if (RunningOnValgrind()) {
      // no stats as Valgrind uses its own malloc.
    } else {
      PrintStats(level);
    }

Alternatively, the RunningOnValgrind check could be done inside
PrintStats.

Note: the above segv was produced with a statically linked tcmalloc
library and a valgrind 3.9.0 SVN, using
   valgrind --soname-synonyms=somalloc=NONE
statically_linked_tcmalloc_program

I suppose the bug will also be triggered with a dynamically linked
tcmalloc.
For a dynamically linked tcmalloc, the argument
--soname-synonyms=somalloc=NONE should be changed (e.g.
--soname-synonyms=somalloc=*tcmalloc*)

Original issue reported on code.google.com by philippe...@gmail.com on 4 Jun 2013 at 7:47

GoogleCodeExporter commented 9 years ago

Original comment by alkondratenko on 6 Jul 2013 at 11:14

GoogleCodeExporter commented 9 years ago
merged a fix. Thanks for finding and reporting it

Original comment by alkondratenko on 15 Sep 2013 at 12:21