I am testing C code for memory leaks and can't seem to find the source of the leaks because there are 0 errors. Valgrind reports that there is a (quite significant) memory leak:
==30492== Memcheck, a memory error detector
==30492== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==30492== Using Valgrind-3.14.0.GIT and LibVEX; rerun with -h for copyright
info
==30492== Command: ./a.out --leak-check=full --track-origins=yes
==30492==
(This is where the input and output cases are displayed, which are a lot)
==30492==
==30492== HEAP SUMMARY:
==30492== in use at exit: 39,155 bytes in 167 blocks
==30492== total heap usage: 380 allocs, 213 frees, 53,426 bytes allocated
==30492==
==30492== LEAK SUMMARY:
==30492== definitely lost: 20,480 bytes in 2 blocks
==30492== indirectly lost: 2,064 bytes in 1 blocks
==30492== possibly lost: 0 bytes in 0 blocks
==30492== still reachable: 348 bytes in 9 blocks
==30492== suppressed: 16,263 bytes in 155 blocks
==30492== Rerun with --leak-check=full to see details of leaked memory
==30492==
==30492== For counts of detected and suppressed errors, rerun with: -v
==30492== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
The code is written in a few files and consists of hundreds of lines, so posting it here would probably be a bit much. Could anyone explain what could be the problem here? Or would you need to see the actual code to give an answer? I can find only little documentation on valgrind and am quite stuck here.
(valgrind suggests to rerun with --leak-check=full, but that is what I did to get this output)
It is possible to get false positives (e.g. in shared library initializers, or things like libcrypto.so which does leak some allocation).
However, you should always check - most likely you're forgetting some allocation.
In your output, we can see:
Command: ./a.out --leak-check=full --track-origins=yes`
This indicates you've invoked valgrind with:
valgrind ./a.out --leak-check=full --track-origins=yes
You should use this:
valgrind --leak-check=full --track-origins=yes ./a.out
If you find a leak (or other diagnostic) that you cannot control because it's internal to a third-party library, you can make a suppression file
Related
I have developed a pure-C implementation of FIFO lists (queues) in files fifo.h and fifo.c, and have written a test programme testfifo.c which I compile to ./bin/testfifo. The node structure is defined in list.h.
I run my programme through Valgrind on OS X 10.6 like this
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./bin/testfifo
and get the following output
==54688== Memcheck, a memory error detector
==54688== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==54688== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==54688== Command: bin/testfifo
==54688==
--54688-- bin/testfifo:
--54688-- dSYM directory is missing; consider using --dsymutil=yes
==54688==
==54688== HEAP SUMMARY:
==54688== in use at exit: 88 bytes in 1 blocks
==54688== total heap usage: 11 allocs, 10 frees, 248 bytes allocated
==54688==
==54688== LEAK SUMMARY:
==54688== definitely lost: 0 bytes in 0 blocks
==54688== indirectly lost: 0 bytes in 0 blocks
==54688== possibly lost: 0 bytes in 0 blocks
==54688== still reachable: 0 bytes in 0 blocks
==54688== suppressed: 88 bytes in 1 blocks
==54688==
==54688== For counts of detected and suppressed errors, rerun with: -v
==54688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
According to the leak summary, there are no leaks, but I am still wondering what the "suppressed" leaks are. Besides, the number of alloc's and free's do not match, and hence I am unsure if there are leaks or not.
----EDIT----
Running
valgrind --tool=memcheck --leak-check=full --show-reachable=yes -v ./bin/testfifo
on OS X 10.6 produces a quite long and confusing output, but I have run
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./bin/testfifo
on a Linux machine an got this output:
==32688== Memcheck, a memory error detector
==32688== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==32688== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==32688== Command: bin/testfifo
==32688==
==32688==
==32688== HEAP SUMMARY:
==32688== in use at exit: 0 bytes in 0 blocks
==32688== total heap usage: 10 allocs, 10 frees, 160 bytes allocated
==32688==
==32688== All heap blocks were freed -- no leaks are possible
==32688==
==32688== For counts of detected and suppressed errors, rerun with: -v
==32688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
alloc's and free's now match, so the extra alloc on OS X seems to be due to some system library, as has been suggested.
I have run the very same command with the -v option, in order to reveal the 4 suppressed errors, but I have not got any easily understandable new information.
Those are leaks outside of your code, in (probably shared) libraries or known false positives. Running valgrind with -v should inform you about the suppressions used.
I wrote a program that sometimes leaks in its child processes. To try to figure out why, I run
valgrind --leak-check=full --trace-children=yes ./shell
The --leak-check=full works correctly on the parent process, but it is explicitly not applied to any child processes. For example,
==14044== Memcheck, a memory error detector
==14044== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14044== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==14044== Command: ./shell
==14044==
Shell by: user
(pid=14044)/home/user/user/shell$ invalid_command --flag-that-is-ignored
Command executed by pid=14044
invalid_command: not found
==14046==
==14046== HEAP SUMMARY:
==14046== in use at exit: 120 bytes in 1 blocks
==14046== total heap usage: 16 allocs, 15 frees, 552 bytes allocated
==14046==
==14046== LEAK SUMMARY:
==14046== definitely lost: 0 bytes in 0 blocks
==14046== indirectly lost: 0 bytes in 0 blocks
==14046== possibly lost: 0 bytes in 0 blocks
==14046== still reachable: 120 bytes in 1 blocks
==14046== suppressed: 0 bytes in 0 blocks
==14046== Reachable blocks (those to which a pointer was found) are not shown.
==14046== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==14046==
==14046== For counts of detected and suppressed errors, rerun with: -v
==14046== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
(pid=14044)/home/user/user/shell$ exit
==14044==
==14044== HEAP SUMMARY:
==14044== in use at exit: 0 bytes in 0 blocks
==14044== total heap usage: 26 allocs, 26 frees, 845 bytes allocated
==14044==
==14044== All heap blocks were freed -- no leaks are possible
==14044==
==14044== For counts of detected and suppressed errors, rerun with: -v
==14044== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
As you can see, when I call invalid_command from within my program, it correctly sees that invalid_command is not a command and prints an error accordingly. This child process then cleans up and exits, and valgrind prints out a leak summary. But the leak summary says rerun with: --leak-check=full despite the fact that I did run it with that flag!
When I exit the parent process, I have no memory leaks and it appears that --leak-check=full applied to the parent process correctly.
How can I make --leak-check=full apply to the child processes that I create? The program is written in C and I'm just using the normal fork(); exec(); wait(); paradigm.
The following combination of options solved my problem:
valgrind --leak-check=full --show-leak-kinds=all --trace-children=yes ./shell
If any of these are omitted, the output will be as shown above (it will not include line numbers).
I think you are looking for the --trace-children=yes option.
I am trying to connect to mongodb with the C-API and my code seems to work fine. However, close inspection with Valgrind complains that I am doing illegal stuff.
My program accepts the parameter -h <hostname>, and then translates this string to a mongodb_uri and then tries to connect to mongodb:
*client_p = mongoc_client_new(host);
if (!*client_p) {
log_die("Failed to parse URI!");
}
My program runs as expected but when I inspect it with valgrind it the call to mongoc_client_new causes SIGSEGV:
==28775== Memcheck, a memory error detector
==28775== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==28775== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==28775== Command: ./coll2tde -h mongodb://localhost -d test -c testq
==28775==
aTrying to connect to mongodb://localhost
2014/12/25 22:22:21.0255: [28775]: DEBUG: cluster: Client initialized in direct mode.
==28775== Jump to the invalid address stated on the next line
==28775== at 0xFFFFFFFFFF600800: ???
==28775== by 0x402722: get_cursor (mongo.c:26)
==28775== by 0x402330: main (coll2tde.c:120)
==28775== Address 0xffffffffff600800 is not stack'd, malloc'd or (recently) free'd
==28775==
==28775==
==28775== Process terminating with default action of signal 11 (SIGSEGV)
==28775== Bad permissions for mapped region at address 0xFFFFFFFFFF600800
==28775== at 0xFFFFFFFFFF600800: ???
==28775== by 0x402722: get_cursor (mongo.c:26)
==28775== by 0x402330: main (coll2tde.c:120)
==28775==
==28775== HEAP SUMMARY:
==28775== in use at exit: 114,751 bytes in 3,194 blocks
==28775== total heap usage: 3,615 allocs, 421 frees, 177,386 bytes allocated
==28775==
==28775== LEAK SUMMARY:
==28775== definitely lost: 6,784 bytes in 1 blocks
==28775== indirectly lost: 2,968 bytes in 11 blocks
==28775== possibly lost: 1,462 bytes in 19 blocks
==28775== still reachable: 103,537 bytes in 3,163 blocks
==28775== suppressed: 0 bytes in 0 blocks
==28775== Rerun with --leak-check=full to see details of leaked memory
==28775==
==28775== For counts of detected and suppressed errors, rerun with: -v
==28775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 6)
Killed
At the beginning I thought it's a problem with my code, but then I compile the example from mogoc_client documentation and saw the same behavior. I would like to know if it is a bug or can this be safely ignored.
After spending a couple of hours trying to figuring this issue, it turns out this is a problem with older versions of Valgrind (3.7 on Debian Wheezy). I compiled Valgrind in version 3.10.1 from upstream sources and this issue disappeared.
In my program, even if do all the obvious housekeeping, such as calling cairo_destroy(), cairo_surface_destroy()..., valgrind always finds memory leaks, the leaks are in cairo dependencies (freetype, pixman, ...). How do I cleanup after cairo, so that valgrind won't detect any leaks, or are the leaks normal?
Sample output
==1861== HEAP SUMMARY:
==1861== in use at exit: 1,996,663 bytes in 532 blocks
==1861== total heap usage: 21,915 allocs, 21,383 frees, 95,411,698 bytes allocated
==1861==
==1861== LEAK SUMMARY:
==1861== definitely lost: 0 bytes in 0 blocks
==1861== indirectly lost: 0 bytes in 0 blocks
==1861== possibly lost: 0 bytes in 0 blocks
==1861== still reachable: 1,996,663 bytes in 532 blocks
==1861== suppressed: 0 bytes in 0 blocks
==1861== Reachable blocks (those to which a pointer was found) are not shown.
==1861== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1861==
==1861== For counts of detected and suppressed errors, rerun with: -v
==1861== Use --track-origins=yes to see where uninitialised values come from
==1861== ERROR SUMMARY: 1961 errors from 7 contexts (suppressed: 1 from 1)
UPDATE:
This question says, the "leaks" are normal, does there exist a way to do the cleanup, so valgrind becomes happy?
For cairo there is cairo_debug_reset_static_data().
While writing this as a comment, I was looking into pixman's source and the implementation of _pixman_choose_implementation() and apparently you cannot "clean up" pixman.
I have no clue about freetype.
Edit:
For fontconfig (related to freetype, so possibly interesting here), there is FcFini().
I have developed a pure-C implementation of FIFO lists (queues) in files fifo.h and fifo.c, and have written a test programme testfifo.c which I compile to ./bin/testfifo. The node structure is defined in list.h.
I run my programme through Valgrind on OS X 10.6 like this
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./bin/testfifo
and get the following output
==54688== Memcheck, a memory error detector
==54688== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==54688== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==54688== Command: bin/testfifo
==54688==
--54688-- bin/testfifo:
--54688-- dSYM directory is missing; consider using --dsymutil=yes
==54688==
==54688== HEAP SUMMARY:
==54688== in use at exit: 88 bytes in 1 blocks
==54688== total heap usage: 11 allocs, 10 frees, 248 bytes allocated
==54688==
==54688== LEAK SUMMARY:
==54688== definitely lost: 0 bytes in 0 blocks
==54688== indirectly lost: 0 bytes in 0 blocks
==54688== possibly lost: 0 bytes in 0 blocks
==54688== still reachable: 0 bytes in 0 blocks
==54688== suppressed: 88 bytes in 1 blocks
==54688==
==54688== For counts of detected and suppressed errors, rerun with: -v
==54688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
According to the leak summary, there are no leaks, but I am still wondering what the "suppressed" leaks are. Besides, the number of alloc's and free's do not match, and hence I am unsure if there are leaks or not.
----EDIT----
Running
valgrind --tool=memcheck --leak-check=full --show-reachable=yes -v ./bin/testfifo
on OS X 10.6 produces a quite long and confusing output, but I have run
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./bin/testfifo
on a Linux machine an got this output:
==32688== Memcheck, a memory error detector
==32688== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==32688== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==32688== Command: bin/testfifo
==32688==
==32688==
==32688== HEAP SUMMARY:
==32688== in use at exit: 0 bytes in 0 blocks
==32688== total heap usage: 10 allocs, 10 frees, 160 bytes allocated
==32688==
==32688== All heap blocks were freed -- no leaks are possible
==32688==
==32688== For counts of detected and suppressed errors, rerun with: -v
==32688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
alloc's and free's now match, so the extra alloc on OS X seems to be due to some system library, as has been suggested.
I have run the very same command with the -v option, in order to reveal the 4 suppressed errors, but I have not got any easily understandable new information.
Those are leaks outside of your code, in (probably shared) libraries or known false positives. Running valgrind with -v should inform you about the suppressions used.