warning for not using free() malloc - c

Are there any safeguards built into GCC that check for memory leaks? If so how can I use them? When I compile with "gcc -Wall -o run run.c", the compiler does not seem to care if any allocated heap-space is being freed at the end of the code. I could not find any simple fixes for this on Google.
Thanks much for your time.
EDIT:
Google Searches did point to Valgrind among other tools. But I was curious as to why the compiler cant deal with this issue. As a newbie, it seemed a simple enough task to check if every "malloc" has a "free" associated with it.

There are two ways to analyze code for problems - static analysis and run-time analysis. Static analysis reads the code - this is what compilers do really well. Run-time analysis for code problems happens when the code is linked against another set of libraries that see what the code actually does as it runs under surveillance. Finding memory leaks is difficult for static analysis but not for a run-time analysis package.
Other run-time analyses are things like code coverage - does all parts of your code run? gcov does this, like valgrind and electric fence look for memory problems like leaks.
So, no, there are no really good compiler safeguards for testing memory leaks.

There is -fsanitize=leak GCC flag.
It overrides malloc/calloc/free to make them count allocated and freed blocks of memory.
If your program is compiled with this flag, it prints information about detected leaks to the terminal after execution.
You can read about it here and here.
Also, I have never used it, so this answer is completely based on GCC manual.

Related

GCC warn for non-freed heap blocks

So the question is simple is there a way to tell the GCC that I want to get warned if I do not free a heap allocated block? I know that we can have non-freed blocks for some purposes/we already reached end of program or something like that.
int main(){
int *a = malloc(sizeof(int));
return 0;
}
If I can get a warning even for this it would be awesome.
This is not a possible job for GCC to do. Static analysis cannot prove that a free is forgotten, that's the job of run-time analysers like valgrind's memcheck, or eventually gcc -fsanitize=leak, which I haven't seen there yet, only with clang -fsanitize=leak.
But you won't get a compile-time warning, even when gcc or clang supports it. It will be a run-time warning.
The compiler cannot predict and warn for non-freed blocks. This is runtime job, not compile time. You can implement your own malloc-free-check subsystem or modify memory management library.

Examples showing how switching to a modern C compiler can help discover bugs?

I am preparing a note to convince people that switching from GCC2 to GCC4 (as a C compiler) is a good idea.
In particular, I think it can reveal existing bugs. I would like to give examples, but as a Java programmer my experience of this situations is limited. One example is return type checking, I guess.
What are other convincing examples showing that switching to a modern compiler can help discover bugs that exist in C code?
Well, some gcc options which is very useful in bugs discovery:
-finstrument-functions - helps to build function call stack tracer. Especially on architectures where built-in __builtin_return_address() scope is limited only to current function at hand. Stack tracer together with linker's symbol file generated with -Map linker option are indispensable tools for detecting memory leaks (suppose you develop embedded system on which Valgrind can't be run or etc.)
-fstack-protector-all is very useful for detecting where code writes bytes to memory in out-of-buffer place. So this option detects buffer-overflow type bugs.
Errr... just those two options are in mind. Possibly there are more which I don't know ...
I assume these people have a particular piece of code they're using gcc2 with. The best thing to do might be to just take that code and compile it in gcc4 with all possible warnings turned on and compare the difference.
Some other differences between gcc2 and gcc4 are likely to be:
Better compile times (gcc4 is probably faster)
Much better code run times (gcc4 is better at optimizing, and has knowledge of CPU architecture that did not exist when gcc2 came out).
Better warning/error messages
I'm sure there are some interesting new GNU C extensions in gcc4

How can I do automatic memory management in C?

In C memory allocation/deallocation done by malloc and free.
In C++ memory allocation/deallocation done by new and delete.
There are some solutions in C++ for automatic memory management like:
Smart Pointers.
RAII (Resource Acquisition Is Initialization)
Reference counting and cyclic references
...
But how can I do automatic memory management in C?
Is there any solutions for AUTOMATIC memory management in C?
Is there any guidelines or something like that for C?
I want when I foget free a block of memory:
My code doesn't compile
-- or --
Memory automatically deallocated
And then I say: Oh, C is better than C++, Java and C#. :-)
You may use a Boehm garbage collector library.
As answered by Juraj Blaho, you can use a garbage collection library, such as the Boehm conservative garbage collector, but there are other ones : Ravenbrook's memory pool system, my (unmaintained) Qish GC, Matthew Plant's GC, etc...
And often, you can write your own garbage collector specialized for your use case. You could use in C the techniques mentioned in your question (smart pointers, reference counting), but you can also implement a mark & sweep GC, or a copying GC.
An important issue when coding your GC is to keep track of local pointer variables (to garbage collected data). You could keep them in local struct and chain them together.
I strongly suggest to read more about GC, e.g. the GC handbook. The algorithms there are useful in many situations.
You could even customize your GCC compiler (e.g. using MELT) to add checks or to generate code (e.g. code to scan local variables) for your particular GC implementation. Or you could use some pre-processor (e.g. GPP) for that
In practice, Boehm's GC is often good enough.
Notice that liveness of some data is a whole-program property. So it better to think about GC very early in the design phase of your software development.
Notice also that detecting reliably memory leaks by static source code analysis is in general impossible (undecidable), since it can be proven equivalent to the halting problem.
For linux, I use valgrind. Sure, the original reason for why valgrind was build was to debug your code, but it does a lot more. It will even tell you where potentially erroneous code could be in a non-invasive way. My own command line of choice is as follows.
# Install valgrind. Remove this line of code if you already have it installed
apt install valgrind
# Now, compile and valgrind the C
gcc main.c -Werror -fshort-enums -std=gnu11 -Og -g3 -dg -gdwarf-2 -rdynamic -o main
valgrind --quiet --leak-check=yes --tool=memcheck -Wall ./main
Hope this helps. ~ Happy Coding!

dlmalloc crash on Win7

For some time now I've been happily using dlmalloc for a cross-platform project (Windows, Mac OS X, Ubuntu). Recently, however, it seems that using dlmalloc leads to a crash-on-exit on Windows 7.
To make sure that it wasn't something goofy in my project, I created a super-minimal test program-- it doesn't do anything but return from main. One version ("malloctest") links to dlmalloc and the other ("regulartest") doesn't. On WinXP, both run fine. On Windows 7, malloctest crashes. You can see screencasts of the tests here.
My question is: why is this happening? Is it a bug in dlmalloc? Or has the loader in Windows 7 changed? Is there a workaround?
fyi, here is the test code (test.cpp):
#include <stdio.h>
int main() {
return 0;
}
and here is the nmake makefile:
all: regulartest.exe malloctest.exe
malloctest.exe: malloc.obj test.obj
link /out:$# $**
regulartest.exe: test.obj
link /out:$# $**
clean:
del *.exe *.obj
For brevity, I won't include the dlmalloc source in this post, but you can get it (v2.8.4) here.
Edit: See these other relavent SO posts:
Is there a way to redefine malloc at link time on Windows?
Globally override malloc in visual c++
Looks like a bug in the C runtime. Using Visual Studio 2008 on Windows 7, I reproduced the same problem. After some quick debugging by putting breakpoints in dlmalloc and dlfree, I saw that dlfree was getting called with an address that it never returned earlier from dlmalloc, and then it was hitting an access violation shortly thereafter.
Thankfully, the C runtime's source code is distributed along with VS, so I could see that this call to free was coming from the __endstdio function in _file.c. The corresponding allocation was in __initstdio, and it was calling _calloc_crt to allocate its memory. _calloc_crt calls _calloc_impl, which calls HeapAlloc to get memory. _malloc_crt (used elsewhere in the C runtime, such as to allocate memory for the environment and for argv), on the other hand, calls straight to malloc, and _free_crt calls straight to free.
So, for the memory that gets allocated with _malloc_crt and freed with _free_crt, everything is fine and dandy. But for the memory that gets allocated with _calloc_crt and freed with _free_crt, bad things happen.
I don't know if replacing malloc like this is supported -- if it is, then this is a bug with the CRT. If not, I'd suggest looking into a different C runtime (e.g. MinGW or Cygwin GCC).
Using dlmalloc in cross-platform code is an oxymoron. Replacing any standard C functions (especially malloc and family) results in undefined behavior. The closest thing to a portable way to replace malloc is using search-and-replace (not #define; that's also UB) on the source files to call (for example) my_malloc instead of malloc. Note that internal C library functions will still use their standard malloc, so if the two conflict, things will still blow up. Basically, trying to replace malloc is just really misguided. If your system really has a broken malloc implementation (too slow, too much fragmentation, etc.) then you need to do your replacement in an implementation-specific way, and disable the replacement on all systems except ones where you've carefully checked that your implementation-specific replacement works correctly.

Can I make valgrind ignore glibc libraries?

Is it possible to tell valgrind to ignore some set of libraries?
Specifically glibc libraries..
Actual Problem:
I have some code that runs fine in normal execution. No leaks etc.
When I try to run it through valgrind, I get core dumps and program restarts/stops.
Core usually points to glibc functions (usually fseek, mutex etc).
I understand that there might be some issue with incompatible glibc / valgrind version.
I tried various valgrind releases and glibc versions but no luck.
Any suggestions?
This probably doesn't answer your question, but will provide you the specifics of how to suppress certain errors (which others have alluded to but have not described in detail):
First, run valgrind as follows:
valgrind --gen-suppressions=all --log-file=valgrind.out ./a.out
Now the output file valgrind.out will contain some automatically-generated suppression blocks like the following:
{
stupid sendmsg bug: http://sourceware.org/bugzilla/show_bug.cgi?id=14687
Memcheck:Param
sendmsg(mmsg[0].msg_hdr)
fun:sendmmsg
obj:/usr/lib/libresolv-2.17.so
fun:__libc_res_nquery
obj:/usr/lib/libresolv-2.17.so
fun:__libc_res_nsearch
fun:_nss_dns_gethostbyname4_r
fun:gaih_inet
fun:getaddrinfo
fun:get_socket_fd
fun:main
}
Where "stupid sendmsg bug" and the link are the name that I added to refer to this block. Now, save that block to sendmsg.supp and tell valgrind about that file on the next run:
valgrind --log-file=valgrind --suppressions=sendmsg.supp ./a.out
And valgrind will graciously ignore that stupid upstream bug.
As noted by unwind, valgrind has an elaborate mechanism for controlling which procedures are instrumented and how. But both valgrind and glibc are complicated beasts, and you really, really, really don't want to do this. The easy way to get a glibc and valgrind that are mutually compatible is to get both from the Linux distro of your choice. Things should "just work", and if they don't, you have somebody to complain to.
Yes, look into Valgrind's suppression system.
You probably want to ask about this on the Valgrind user's mailing list (which is extremely helpful). You can suppress output from certain calls, however, suppressing the noise is all you are doing. The calls are still going through Valgrind.
To accomplish what you need, you (ideally) match Valgrind appropriately with glibc or use the macros in valgrind/valgrind.h to work around them. Using those, yes, you can tell valgrind not to touch certain things. I'm not sure what calls are borking everything, however you can also (selectively) not run bits of code in your own program if its run under valgrind. See the RUNNING_ON_VALGRIND macro in valgrind/valgrind.h.
The other thing that comes to mind is to make sure that Valgrind was compiled correctly to deal with threads. Keep in mind that atomic operations under Valgrind could cause your program to crash during racey operations, where it otherwise might not, if not properly configured.
If you have been swapping versions of valgrind and glibc, there's a chance you found a match, but incorrectly configured valgrind at build time.

Resources