valgrind detects false memleak?
Hi, Valgrind reports a memory leak on my program for certain variable. To find out on what case I fail to free variable, I printed some messages before the allocation/deallocation of the relevant variable, say printf("ALLOC\n") before calloc and printf("FREE\n") after free. The funny thing is, when I ran and counted the number of messages, there was equal number of ALLOC messages and FREE messages. Which mean, no memory leak at all. Right now I assume that valgrind falsely detect some memleaks. However, this leaves me some uncomfortable feeling, as if sometime later, my program will cause the computer to explode (ok, exaggeration here :). Any thoughts on that? Btw, I use the standard calloc/free provided by glibc, not some 3rd party ones. TIA. Regards, Verdi -- 5 GB Mailbox, 50 FreeSMS http://www.gmx.net/de/go/promail +++ GMX - die erste Adresse f�r Mail, Message, More +++
On Wed, 21 Sep 2005, Verdi March wrote:
Hi,
Hi,
Right now I assume that valgrind falsely detect some memleaks. However, this leaves me some uncomfortable feeling, as if sometime later, my program will cause the computer to explode (ok, exaggeration here :).
Any thoughts on that? Btw, I use the standard calloc/free provided by glibc, not some 3rd party ones.
What is the exact message you get? How do you call valgrind? Is it possible to post/email a small compilable example which shows your problem?
TIA.
Regards, Verdi
Best regards, Aschwin Marsman -- aschwin@marsman.org http://www.marsman.org
Aschwin Marsman wrote:
What is the exact message you get?
How do you call valgrind?
The program is a simulator, called rsim. I call valgrind with the following: valgrind --leak-check=yes ./rsim -i haha.ev The -i haha.ev is arguments for rsim. And here're the output: ------------------------------------------------------------------------- ==18483== ==18483== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 20 from 3) ==18483== malloc/free: in use at exit: 73828228 bytes in 4129 blocks. ==18483== malloc/free: 4724 allocs, 595 frees, 73902008 bytes allocated. ==18483== For counts of detected errors, rerun with: -v ==18483== searching for pointers to 4129 not-freed blocks. ==18483== checked 82564948 bytes. ==18483== ==18483== ==18483== 48 bytes in 2 blocks are definitely lost in loss record 5 of 14 ==18483== at 0x1B901B95: calloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==18483== by 0x8053D02: newRequest (request.c:51) ==18483== by 0x8056096: stabilize (stabilize.c:46) ==18483== by 0x8056797: main (sim.c:126) ==18483== ==18483== LEAK SUMMARY: ==18483== definitely lost: 48 bytes in 2 blocks. ==18483== possibly lost: 0 bytes in 0 blocks. ==18483== still reachable: 73828180 bytes in 4127 blocks. ==18483== suppressed: 0 bytes in 0 blocks. ==18483== Reachable blocks (those to which a pointer was found) are not shown. ==18483== To see them, rerun with: --show-reachable=yes -------------------------------------------------------------------------
Is it possible to post/email a small compilable example which shows your problem?
Unfortunately that'll be quite a difficult thing to do :( I'll give a summary instead, hope it can be useful: The newRequest() functions is used almost everywhere, but only in stabilize() that valgrind detected a memleak. What stabilize() does is: Request r = newRequest(...); printf("STAB_NEW\n"); //Only this function creates request with this req_type r->type = REQ_TYPE_STABILIZE; if (TRUE) { //continue processing this request //processRequest(); } else { //cancel request free(r); printf("STAB_FREE\n"); } A request is processed in another function, processRequest(). processRequst() should occur sometime in the future, so instead of stabilize() invoke processRequest(), there is "scheduler" that invokes processRequest(). Note that the simulator is sequential, not multi-threaded. What processRequest() does is to simulate the request until the request is finished. So, there will be several free(r) in processRequest(). Before every free(r) in processRequest(), I print a message. At the end, it'll look like this: if (must_free_request) { if (r->type == REQ_TYPE_STABILIZE) printf("STAB_FREE\n"); free(r); } As you can see, there's nothing fancy in the code. Regards, Verdi -- 5 GB Mailbox, 50 FreeSMS http://www.gmx.net/de/go/promail +++ GMX - die erste Adresse f�r Mail, Message, More +++
Hi Verdi I use valgrind quite extensively and, in my experience, valgrind does not lie ... If you do not believe valgrind, try some other memory debugger such as dmalloc or Intel's pin. Or write a small shared library overloading malloc/calloc/free and keeping a log of each memory request and preload it into your application via LD_PRELOAD. Regards, Vadym Krevs Verdi March wrote:
Aschwin Marsman wrote:
What is the exact message you get?
How do you call valgrind?
The program is a simulator, called rsim. I call valgrind with the following: valgrind --leak-check=yes ./rsim -i haha.ev The -i haha.ev is arguments for rsim.
And here're the output: ------------------------------------------------------------------------- ==18483== ==18483== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 20 from 3) ==18483== malloc/free: in use at exit: 73828228 bytes in 4129 blocks. ==18483== malloc/free: 4724 allocs, 595 frees, 73902008 bytes allocated. ==18483== For counts of detected errors, rerun with: -v ==18483== searching for pointers to 4129 not-freed blocks. ==18483== checked 82564948 bytes. ==18483== ==18483== ==18483== 48 bytes in 2 blocks are definitely lost in loss record 5 of 14 ==18483== at 0x1B901B95: calloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==18483== by 0x8053D02: newRequest (request.c:51) ==18483== by 0x8056096: stabilize (stabilize.c:46) ==18483== by 0x8056797: main (sim.c:126) ==18483== ==18483== LEAK SUMMARY: ==18483== definitely lost: 48 bytes in 2 blocks. ==18483== possibly lost: 0 bytes in 0 blocks. ==18483== still reachable: 73828180 bytes in 4127 blocks. ==18483== suppressed: 0 bytes in 0 blocks. ==18483== Reachable blocks (those to which a pointer was found) are not shown. ==18483== To see them, rerun with: --show-reachable=yes -------------------------------------------------------------------------
Is it possible to post/email a small compilable example which shows your problem?
Unfortunately that'll be quite a difficult thing to do :( I'll give a summary instead, hope it can be useful:
The newRequest() functions is used almost everywhere, but only in stabilize() that valgrind detected a memleak.
What stabilize() does is: Request r = newRequest(...); printf("STAB_NEW\n");
//Only this function creates request with this req_type r->type = REQ_TYPE_STABILIZE;
if (TRUE) { //continue processing this request //processRequest(); } else { //cancel request free(r); printf("STAB_FREE\n"); }
A request is processed in another function, processRequest(). processRequst() should occur sometime in the future, so instead of stabilize() invoke processRequest(), there is "scheduler" that invokes processRequest(). Note that the simulator is sequential, not multi-threaded.
What processRequest() does is to simulate the request until the request is finished. So, there will be several free(r) in processRequest(). Before every free(r) in processRequest(), I print a message. At the end, it'll look like this: if (must_free_request) { if (r->type == REQ_TYPE_STABILIZE) printf("STAB_FREE\n");
free(r); }
As you can see, there's nothing fancy in the code.
Regards, Verdi
********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message.
Hi Vadym, On Wednesday 21 September 2005 20:00, Vadym Krevs wrote:
I use valgrind quite extensively and, in my experience, valgrind does not lie ...
Yes, that's what I've experienced too. This is the first time I encounter this puzzle.
If you do not believe valgrind, try some other memory debugger such as dmalloc or Intel's pin.
Well, right now with the data set I tried, the memory consumption is still acceptable (arround 40% of 1GB, the last time I check). If the machines get trashed, then I must be working on this again, otherwise, I'll just put this on my todo lists :).
Or write a small shared library overloading malloc/calloc/free and keeping a log of each memory request and preload it into your application via LD_PRELOAD.
Yes, that's basically what I've done, although I did it manually, inserting printf into the programs, after allocation and deallocation. Regards, Verdi
On Wed, 21 Sep 2005, Verdi March wrote:
Aschwin Marsman wrote:
What's the version of valgrind you are using? The current version you should use is valgrind-3.0.1.
The program is a simulator, called rsim. I call valgrind with the following: valgrind --leak-check=yes ./rsim -i haha.ev The -i haha.ev is arguments for rsim.
And here're the output: ------------------------------------------------------------------------- ==18483== ==18483== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 20 from 3) ==18483== malloc/free: in use at exit: 73828228 bytes in 4129 blocks. ==18483== malloc/free: 4724 allocs, 595 frees, 73902008 bytes allocated. ==18483== For counts of detected errors, rerun with: -v ==18483== searching for pointers to 4129 not-freed blocks. ==18483== checked 82564948 bytes. ==18483== ==18483== ==18483== 48 bytes in 2 blocks are definitely lost in loss record 5 of 14 ==18483== at 0x1B901B95: calloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==18483== by 0x8053D02: newRequest (request.c:51) ==18483== by 0x8056096: stabilize (stabilize.c:46) ==18483== by 0x8056797: main (sim.c:126) ==18483== ==18483== LEAK SUMMARY: ==18483== definitely lost: 48 bytes in 2 blocks. ==18483== possibly lost: 0 bytes in 0 blocks. ==18483== still reachable: 73828180 bytes in 4127 blocks. ==18483== suppressed: 0 bytes in 0 blocks. ==18483== Reachable blocks (those to which a pointer was found) are not shown. ==18483== To see them, rerun with: --show-reachable=yes -------------------------------------------------------------------------
Is it possible to post/email a small compilable example which shows your problem?
Unfortunately that'll be quite a difficult thing to do :( I'll give a summary instead, hope it can be useful:
The newRequest() functions is used almost everywhere, but only in stabilize() that valgrind detected a memleak.
What stabilize() does is: Request r = newRequest(...); printf("STAB_NEW\n");
If you also print the pointers you can see if all pointers allocated are also freed. For this you can also use the suggestions in the other reply.
//Only this function creates request with this req_type r->type = REQ_TYPE_STABILIZE;
if (TRUE) { //continue processing this request //processRequest(); } else {
I don't understand this pseudo code, you will never reach these statements.
//cancel request free(r); printf("STAB_FREE\n"); }
A request is processed in another function, processRequest(). processRequst() should occur sometime in the future, so instead of stabilize() invoke processRequest(), there is "scheduler" that invokes processRequest(). Note that the simulator is sequential, not multi-threaded.
What processRequest() does is to simulate the request until the request is finished. So, there will be several free(r) in processRequest(). Before every free(r) in processRequest(), I print a message. At the end, it'll look like this: if (must_free_request) { if (r->type == REQ_TYPE_STABILIZE) printf("STAB_FREE\n");
free(r);
The printf will not always be called, the free will...
}
Best regards, Aschwin Marsman -- aschwin@marsman.org http://www.marsman.org
participants (3)
-
Aschwin Marsman
-
Vadym Krevs
-
Verdi March