Segmentation
fault (segfault), which can be triggered by various invalid memory
access, must be the most notorious foe of any C programmer. Sometimes
a segmentation fault happens and goes randomly; sometimes the place
where the program aborts is not the location where the error happens;
sometimes the program reports nothing wrong but just keeps giving
weird results. All these usually cost programmers a lot of time in
debugging. Quickly detecting such errors is one of the most important
topic a C programmer should learn.
Valgrind is one of the most
powerful memory debugger in the world. It is easy to use. We only need
to add -g to compile the source codes and then invoke valgrind
like this:
Valgrind will then report various memory problems
including memory
leak, use of uninitialized memory, use of deallocated memory and
double free. Each error will be reported at the line where the error
first happens. There is no randomness, and most, if not all, kinds of
memory problem can be recovered.
Electric Fence is another elegant memory debugger. It is particularly useful when you cannot find a good test set for valgrind.
To use Electric Fence, you should manually copy libefence.a to a system library directory and link your program to libefence.a: Electric Fence will replace malloc/calloc/realloc/free calls with its own functions which, when an error occurs, causes segmentation fault and makes the program abort. Electric Fence is usually used with gdb. You can easily find where the error happens. The Electric Fence manual page gives more detailed directions.
Glibc provides two methods to debug memory problems. The first method is to use MALLOC_CHECK_environmental varible. By default, it is set to 0 which means nothing is reported when errors happen. If it is set to 1, debugging information will be output on stderr; if set to 2, the program will abort at the place where the error happens. According to my test, this method can detect invalid write operations but not invalid read. Electric Fence works better.
The second way to debug is to use mtrace. Although it is claimed that mtrace can also detect invalid read and write, my test shows that it only helps to debug memory leak. This is still helpful, though, when there is no other good tool to do this efficiently.
Memory debugging is an important issue for a C programmer, and therefore people implement a lot of tools (or here to debug memory errors. I cannot try them all, but I believe valgrind and Electric Fence are sufficient for our use.
Mac OS X provides several native ways to debug memory problems. They are: MallocDebug, debug-enabled malloc and gmalloc. However, I recommend none of them. They are either not easy to use or not powerful enough. My suggestion is to install valgrind on a remote Linux machine if you can easily access to network, or to put valgrind in a virtual machine if you always want to work locally. Electric Fence can be ported to Mac OS X (see also this page). We only need to modify one line in its Makefile. The modified codes can be downloaded from this site as efence_mac-2.1.13.tar.bz2.
Update: Valgrind has been initially ported to Mac OS X by Greg Parker. His patch is available from this page. Nicholas Nethercote now maitains the Mac port of valgrind. His blog provides the status latest development. The source codes can be checked out with: