cynthia / gperftools

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

heapcheck not work correctly. Is it a "live memory" problem? #381

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.vim ./test.cc
2.add the following code

struct AA {
    struct AA *x;
};
int main(){
      struct AA *a = new struct AA;
      struct AA *b = new struct AA;
      a->x = b; 
      b->x = a; 
      return 1;
}

3. compile it:
          g++ test.cc -ltcmalloc -g -o test
4. run with leakage check:
          env HEAPCHECK=normal  ./test 

What is the expected output? What do you see instead?
expect ouput:
The 2 largest leaks:
Using local file ./test.
Leak of 8 bytes in 1 objects allocated from:
        @ 40069a main
        @ 34b461d994 __libc_start_main
        @ 4005d9 _start
Leak of 8 bytes in 1 objects allocated from:
        @ 4006a8 main
        @ 34b461d994 __libc_start_main
        @ 4005d9 _start

Actual ouput:
    WARNING: Perftools heap leak checker is active -- Performance may suffer
   Have memory regions w/o callers: might report false leaks
   No leaks found for check "_main_" (but no 100% guarantee that there aren't any): found 19 reachable heap objects of 604 bytes

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

google-perftools-1.8.1 on Red Hat Enterprise Linux Server release 5.4 

Please provide any additional information below.

Original issue reported on code.google.com by huangjia...@gmail.com on 14 Nov 2011 at 9:47

GoogleCodeExporter commented 9 years ago
Two possibilities here.  One is that normal mode doesn't consider leaks in main 
to be a leak -- I forget the exact rules here.  You can test it by running 
HEAPCHECK=strict and seeing what happens.

The other possibility is that the heap-checker is just missing this leak.  As 
the output says:
} No leaks found for check "_main_" (but no 100% guarantee that there aren't 
any):

In general, allocations that happen very close to program exit are most likely 
for the heap-checker to miss.  (Luckily, they're also the least dangerous.)

Both possibilities could be in play. :-)

Either way, I believe this is expected behavior.

Original comment by csilv...@gmail.com on 14 Nov 2011 at 11:38

GoogleCodeExporter commented 9 years ago
I have tried with strict mode, unfortunately,it still couldn't work.
But with draconian mode, heapcheck can find the leakages.
I don't think this is a expected behavior. If you try the follow
codes(just one more new), heapcheck with normal mode could find the
three leakage.
struct AA {
    struct AA *x;
};
int main()
{
struct AA *a = new struct AA;
struct AA *b = new struct AA;
struct AA *c = new struct AA;
    a->x = b;
    b->x = a;
    return 1;
}

Original comment by huangjia...@gmail.com on 15 Nov 2011 at 12:51

GoogleCodeExporter commented 9 years ago
Right, I meant draconian, not strict.  Thanks for catching that.

My feeling is that draconian will always catch this, and other modes will catch 
this only with some probability.  This is expected behavior not because 
heapchecker doesn't think it's a leak, but because it doesn't promise to find 
all memory leaks.  In general, it finds all memory leaks except ones made very 
close to program exit.

Original comment by csilv...@gmail.com on 15 Nov 2011 at 12:59

GoogleCodeExporter commented 9 years ago
OK, thanks for you explanation. I have to accept this fact that "heap
check  doesn't promise to find all memory leaks ".  Thanks again.

Original comment by huangjia...@gmail.com on 15 Nov 2011 at 2:21

GoogleCodeExporter commented 9 years ago
Well, in draconian mode it may (though I think we still make no promises).  But 
that mode often requires a lot of work to be able to pass cleanly.

Original comment by csilv...@gmail.com on 15 Nov 2011 at 2:36

GoogleCodeExporter commented 9 years ago
The fact this example does not work is pretty bad. I played here with a similar 
sample and got the same result - No leaks unless I turn draconian on. My code 
is below. From what I read in your documentation about "flood" searching memory 
I still do not understand why heapchecker misses this even though pointer which 
ensures "liveness" is wiped out.

// gperftools does NOT find this leak

#include <stdlib.h>
#include <string.h>

void do_leaky_stuff()
{
void * ptr = malloc(300);
 strcpy((char*)ptr, "Whole lotta string characters");
 ptr = 0; // forget about the pointer
}

int main(void)
{
 do_leaky_stuff();
}

Original comment by vlad.tro...@gmail.com on 11 Jul 2014 at 11:29