On Mac OS X, the common way to write C code is to simply use the Xcode IDE. Xcode comes with solid autocomplete functionality and has a built-in instruments app – a performance, analysis, and testing tool for dynamically tracing and profiling your program – which is absolutely critical for preserving your sanity and for revealing any mistakes you might have made that is causing memory leaks and various syntax errors in your non-trivial C applications.
The other alternative tool is, of course, the venerable valgrind.
I was curious to see if I could get valgrind working on my Mac laptop running Mavericks (10.9) as it is not yet officially supported. Attempts to get valgrind installed via both the Macports and Homebrew package managers fail.
Fortunately, I discovered a patched branch by Frederic Germain here – https://github.com/fredericgermain/valgrind/ and and this patched branch seems to work great for Mavericks.
And this works beautifully.
# Make sure I have autoconf and automake both installed.
sudo port -v install automake
sudo port -v install autoconf
# Grab Frederic's patched valgrind on his "homebrew" branch
cd ~/work # My usual project directory
git clone https://github.com/fredericgermain/valgrind/ -b homebrew
# Because he placed VEX as a git submodule, we have to make sure we clone it too
git submodule init
git submodule update
# With VEX submodule now available, we can compile valgrind
./configure --prefix=/usr/local # set the stage for sudo make install to place our compiled valgrind binary as /usr/local/bin/valgrind
sudo make install
And checking that I indeed have valgrind installed.
calvin % which valgrind
And now, to see valgrind in action, checking a simple C program just to verify that valgrind works as advertised.
make program1 # compiles my program1.c source file to program1 binary
We should see the stdout read:-
==49132== Memcheck, a memory error detector
==49132== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==49132== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==49132== Command: ./program1
==49132== WARNING: Support on MacOS 10.8/10.9 is experimental and mostly broken.
==49132== WARNING: Expect incorrect results, assertions and crashes.
==49132== WARNING: In particular, Memcheck on 32-bit programs will fail to
==49132== WARNING: detect any errors associated with heap-allocated data.
==49132== HEAP SUMMARY:
==49132== in use at exit: 29,917 bytes in 378 blocks
==49132== total heap usage: 456 allocs, 78 frees, 35,965 bytes allocated
==49132== LEAK SUMMARY:
==49132== definitely lost: 0 bytes in 0 blocks
==49132== indirectly lost: 0 bytes in 0 blocks
==49132== possibly lost: 0 bytes in 0 blocks
==49132== still reachable: 4,096 bytes in 1 blocks
==49132== suppressed: 25,821 bytes in 377 blocks
==49132== Rerun with --leak-check=full to see details of leaked memory
==49132== For counts of detected and suppressed errors, rerun with: -v
==49132== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 117 from 20)
And that’s it. Notice the warnings of course! As I mentioned, valgrind is not offically supported beyond Mac OS X 10.7 yet.
WARNING: Support on MacOS 10.8/10.9 is experimental and mostly broken.
WARNING: Expect incorrect results, assertions and crashes.
WARNING: In particular, Memcheck on 32-bit programs will fail to
WARNING: detect any errors associated with heap-allocated data.
In any case, it is completely possible to invoke instruments from the command line as well – if you insist on writing C programs without the help of Xcode. And is a much safer bet when you are working on your production C programs. But… that shall be a topic for another day. :-)