Valgrind: suppress one-time memory leaks - c

Valgrind reports multiple memory leaks in my program, some of which are recurring leaks (i.e. they occur in multiple blocks), but most of which are one-timers, i.e. allocations that happen at program initialization and that I don't care to take care of before the program exits. I know I can write suppression files to suppress leaks from specific libraries, functions etc., but I haven't found a way to suppress leaks a limited number of times. Is there a way of doing this?
Currently, I use a small program I wrote to filter Valgrind's report file from one-time leaks (so when a paragraph in the report file starts with X bytes leaked in 1 blocks, that paragraph is removed from the report file), but obviously I'd prefer to configure Valgrind to suppress these leaks instead, not least because my filter does nothing to keep the leak summary accurate.
I'm asking because the leaky initialization code is generated by a compiler that compiles to C from the language in which I'm writing my program and that I have little interest in modifying.

Valgrind does not report errors for allocated memory that is still accessible at program exit, so you have bona fide leaks, even if the amount of memory leaked is fixed and (for the moment) inconsequential. Consider actually freeing your pointers, or else ensuring that they do not go out of scope or get overwritten. Under some circumstances you could use arrays instead of dynamically-allocated memory.
If you insist on using suppressions to silence reporting on genuine leaks, however, then make Valgrind do the work for you. Add the option --gen-suppressions=yes (if you want to interactively select which suppressions to generate) or --gen-suppressions=all (to generate suppressions for all errors) to your valgrind command line. You'll need to copy the suppression descriptors Valgrind outputs into your suppression file.

Related

Memcheck a C program's memory behavior under a limited heap size

I have written a piece of C code, which dynamically allocates some structures, the one after the other. When any of the allocations fails, some of the previously allocated ones have to be freed. While I am able to successfully memcheck the application with no issues when every allocation succeeds, I have not been able to figure out how to use valgrind's memcheck to check the scenarios when any of the allocations fails.
When trying to impose a memory limit externally for the allocations to fail, using ulimit or a virtual machine for example, the limit is imposed to valgrind as well, with it failing as a result. Using tools like qemu make the memory behavior of the executable invisible to valgrind and only the tool's behavior is profiled.
When trying to impose it inside the code using rlimit structs, while it is successfully imposed when the program is executed in isolation and the allocations fail as expected, when run by valgrind it is ignored and the allocations succeed regardless of its value.
The ideal scenario would be for valgrind to allow for a memory restriction, but such an option does not seem to exist. Any proposals on how to memcheck for such memory limited scenarios?

How to make valgrind ignore certain line?

for example
==26460== 2 bytes in 1 blocks are still reachable in loss record 2 of 105
==26460== at 0x4C28BE3: malloc (vg_replace_malloc.c:299)
==26460== by 0x580D889: strdup (in /usr/lib64/libc-2.17.so)
==26460== by 0x4F50AF: init (init.c:468)
==26460== by 0x406D75: main (main.c:825)
I want to not check init.c:468: mode = strdup, i'm sure this only malloc once, and will last whole process life.
Is it possible to make valgrind not check this line?
As I said in my comment: I recommend not to.
But Valgrind does have a feature to suppress warnings.
The most convenient way of suppressing a specific message is supported by the feature dedicated to exactly that purpose:
--gen-suppressions=yes
Which apparently will ouptput the precise suppression syntax for each/any generated message.
See 5.1 in the FAQ:
http://valgrind.org/docs/manual/faq.html#faq.writesupp
(I love their style:
"F:Can you write ... for me?" and I expected a totally adequate
"A:No." But they actually answer
"A: Yes ...". Beyond cool.)
You should fix the leaks; it is far better to do so.
You can't stop Valgrind checking for the leaks, but you can stop it reporting them by suppressing the leaks.
Use:
valgrind --gen-suppressions=yes --leak-check=all -- tested-program …
You can then save the suppressions in a file, say tp.suppressions, and subsequently you use:
valgrind --suppressions=tp.suppressions -- tested-program …
If you work on a Mac like I do, and work with bleeding edge systems, you'll often find it necessary to suppress leaks from the system startup code — memory that's allocated before main() is called and which you cannot therefore control.
OTOH, it is routine that after the new release of macOS, it takes a while to get Valgrind running again. I upgraded to macOS High Sierra 10.13; Valgrind has stopped working again because the kernel isn't recognized.

finding blocks of memory

Is there any way how to find out where the person forgot to free() memory?
Valgrind only says how many allocs and frees there were but not where the person didnt free when he should have. Is there any way how to find out the piece of memory that should be freed?
I guess that what you would like is to have valgrind reporting an error
when you 'lose' the last pointer to a piece of memory.
valgrind does not have such a functionality. There used to be an experimental
tool doing that (--tool=omega), but it is not (anymore?) in the valgrind
repository, IIUC, because there was many false positive and/or false negative.
The closest you can do is to use valgrind + gdb (via vgdb), and put
some breakpoints at various places in your program, and do a leak search
at all these places. With a kind of 'dichotomic' search, you might find
the place where you lose the pointer.
See http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
and http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands
for more details about using gdb with valgrind and doing interactive
leak searches.

How to make valgrind report an error when there are still reachable allocs

I'm writing a compiler that produces C code. The programs produced consist only of the main function, and they use a lot of memory, that is allocated with malloc(). Most of the memory allocated is used only in a small part of the program, and I thought it would be a good idea to free() it after use, since it's not going to be used again. I would be glad, then, if valgrind would report to me about memory not free()d in the end of the program, that is, still reachable memory. I'm using valgrind with --error-exitcode=1 inside a Makefile, to check for this kind of problem automatically.
The question is: is there a way to make valgrind exit with 1 in case there are still reachable allocs?
An alternative to grepping through Valgrind output: modify your compiler so it emits:
int main() { return foo_main(); }
int foo_main() { /* whatever you've emitted before */ }
Assuming you are not assigning allocated blocks to global variables (which would make no sense since you only have one function), you've just transformed "still reachable" into "definitely leaked".
Possibly even better transformation: don't call exit(0) in your main; change it to return 0; instead. The net effect should be same as above -- __libc_main will now call exit for you, and all local variables in main will be out of scope by that time.
The valgrind manual says:
Indirectly lost and still reachable
blocks are not counted as true
"errors", even if --show-reachable=yes
is specified and they are printed;
this is because such blocks don't need
direct fixing by the programmer.
I have found no way to make valgrind report "still reachable"s as error. It seems to be that your only option to do this (other than patching valgrind) is to capture the output of valgrind and parse the "still reachable" line.
The poroper options to use to exit with error when there is a reachable block at exit:
valgrind --tool=memcheck --leak-check=full --show-reachable=yes --errors-for-leak-kinds=all
From Valgrind manual:
Because there are different kinds of leaks with different severities, an interesting question is: which leaks should be counted as true "errors" and which should not?
The answer to this question affects the numbers printed in the ERROR SUMMARY line, and also the effect of the --error-exitcode option. First, a leak is only counted as a true "error" if --leak-check=full is specified. Then, the option --errors-for-leak-kinds= controls the set of leak kinds to consider as errors. The default value is --errors-for-leak-kinds=definite,possible
Alternatively you can have a small shell script in your makefile to grep through output logs of valgrind and exit accordingly.

memory leak debug

What are some techniques in detecting/debugging memory leak if you don't have trace tools?
Intercept all functions that allocate and deallocate memory (depending on the platform, the list may look like: malloc, calloc, realloc, strdup, getcwd, free), and in addition to performing what these functions originally do, save information about the calls somewhere, in a dynamically growing global array probably, protected by synchronization primitives for multithreaded programs.
This information may include function name, amount of memory requested, address of the successfully allocated block, stack trace that lets you figure out what the caller was, and so on. In free(), remove corresponding element from the array (if there are none, a wrong pointer is passed to free which is also a error that's good to be detected early). When the program ends, dump the remaining elements of the array - they will be the blocks that leaked. Don't forget about global objects that allocate and deallocate resources before and after main(), respectively. To properly count those resources, you will need to dump the remaining resources after the last global object gets destroyed, so a small hack of your compiler runtime may be necessary
Check out your loops
Look at where you are allocating variables - do you ever de-allocate them?
Try and reproduce the leak with a small subset of suspected code.
MAKE trace tools - you can always log to a file.
One possibility could be to compile the code and execute it on a system where you can take advantage of built in tools (e.g. libumem on Solaris, or the libc capability on Linux)
Divide and conquer is the best approach. If you have written you code in a systematic way, it should be pretty easy to call subsets of you code. Your best bet is to execute each section of code over and over and see if your memory usage steadily climbs, if not move on to the next section of code.
Also, the wikipedia article on memory leaks has several great links in the references section on detecting memory leaks for different systems (window, macos, linux, etc)
Similar questions on SO:
Memory leak detectors for C
Strategies For Tracking Down Memory Leaks When You’ve Done Everything Wrong
In addition to the manual inspection techniques mentioned by others, you should consider a code analysis tool such as valgrind.
Introduction from their site:
Valgrind is an award-winning
instrumentation framework for building
dynamic analysis tools. There are
Valgrind tools that can automatically
detect many memory management and
threading bugs, and profile your
programs in detail. You can also use
Valgrind to build new tools.
The Valgrind distribution currently
includes six production-quality tools:
a memory error detector, two thread
error detectors, a cache and
branch-prediction profiler, a
call-graph generating cache profiler,
and a heap profiler. It also includes
two experimental tools: a
heap/stack/global array overrun
detector, and a SimPoint basic block
vector generator. It runs on the
following platforms: X86/Linux,
AMD64/Linux, PPC32/Linux, PPC64/Linux,
and X86/Darwin (Mac OS X).
I have used memtrace
http://www.fpx.de/fp/Software/MemTrace/
http://sourceforge.net/projects/memtrace/
You may need to call the statistics function to printout if there are any leaks. Best thing is to call this statistics function before and after a module or piece of code gets executed.
* Warning * Memtrace is kind enough to allow memory overwrite/double free. It detects these anomalies and gracefully avoids any crash.

Resources