finding memory leaks in c code on linux environment - c

hello i got a problem using valgrind
when i use it with valgrind --leak-check=full and afterwards the name of excution file it tells me in which blocks the memory leak is but when i cant find to which pointer i did use free.
is there some sort of flag that tells the name of the pointer.
if there is anyway to tell me where the leak is on visual studio i would very much like to hear about it too

It can't tell you the name of the pointer, because the whole idea of a memory leak is that no pointer points at the memory any more (at least, for the kinds of leaks that Valgrind describes as "definitely lost").
What it can tell you is the source file and line number where the memory was allocated - you then will need to look up that line in your source to figure out where the memory is supposed to be deallocated. For example, if the Valgrind loss record looks like:
==17110== 49 bytes in 1 blocks are definitely lost in loss record 17 of 35
==17110== at 0x4023D6E: malloc (vg_replace_malloc.c:207)
==17110== by 0x80C4CF8: do_foo (foo.c:1161)
==17110== by 0x80AE325: xyzzy (bar.c:466)
==17110== by 0x8097C46: io (bar.c:950)
==17110== by 0x8098163: main (quux.c:1291)
Then you need to look at line 1161 in foo.c, which is within the function do_foo(). That's where the memory was allocated (with malloc()), and only you can say where it should have been freed.

You didn't say which compiler you are using, I suppose gcc?
Do you use -g to have debugging symbols included?

Related

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.

Valgrind: suppress one-time memory leaks

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.

C - Freeing Heap Memory Allocated in Another File

If you have a project that utilizes a makefile which compiles multiple files and headers, does this complicate the heap?
Specifically:
I have a main.c file which includes a header, say test.h. In test.c which is linked to test.h memory is allocated explicitly with malloc. main.ccalls the functions in test.c. For some reason, when I try to to free memory inside of the functions in test.c I always get an error:
main(65245) malloc: *** error for object 0x106d012f8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
...this error occurs even though I never, not even once free any memory at all in the entire makefile stack. Obviously stdlib.h is included. What could be going on? Are there separate heaps for main.c and test.c and whenever the latter is called and the result is returned, the heap memory allocated is already freed? I'm really stumped. I can allocate and free memory in main.c without any issue. They have the same includes.
there is no such thing as 'different files' at run-time. all files are integrated into one big binary code at linkage. So, therefore, there is obviously only one heap.
your problem must be something else, since you never freed a memory, maybe you are trying to free static allocated memory or something like that
also, note that there is a convention which is usually pretty good to prevent memory leaks, which says: the part of the program that allocated the memory, is also responsible to free it. It is not directly connected to your question, but it will be helpful for future to try and do it, in order to prevent memory leaks.
Are you freeing the same addres/pointer in each file? Yes, you get 1 heap unless you specifically try and get multiple heaps. My guess is you are not freeing the same pointer - perhaps a addressing/double pointer error of some sort. You do best to post some source code for us to be sure...
All malloc() calls allocate from the same heap, no matter what file you call them from. You are freeing a pointer that did not come from any malloc() call.
Review your code carefully, print allocated and freed pointer values to debug log.

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.

Resources