Run valgrind from your Mac via a remote Linux machine

valgrind doesn't love your Mac as much as you do

So you decided to write some C/C++ and you want to do so on your Mac since you like the gestures and/or other niceties that a Linux distro can't give you?

Well, given you are on OSX 10.9.x (Mavericks) you'll soon find, that valgrind is not supported there yet. This will eventually get fixed, but by then the next OSX version will be out and you will want to upgrade - only to face the same problem all over again

The Best of Both Worlds

There is a way to work around this issue by running valgrind against your code on a linux machine, virtual or whatever, but keep developing on your Mac.

I happen to have a desktop lying around, which I bought a month before realizing that Windows stinks (entirely different story) and after trying twice to hackintosh it, I installed Ubuntu. So I figured I could use it to develop/test my C code which was leaking memory allover the place.

I tried a few different options and list them here for reference along with the reason why they didn't cut it for me, followed by the final option which worked just perfect.

ssh into the Linux Machine and develop and test there entirely -> ok

That works nicely if you can live with the slight delay between typing and the result appearing in your editor. Not an option for me

Remote Edit Files with Vim -> ok

This is an ok option, but has the disadvantage that you have no context since the file you are editing actually gets scpd into your local tmp dir and back to the remote machine every time you save. Therefore there is no way to quickly see/open related files either with Ctrl-P or NERDTree.

Additionally it is annoying that the local files of your project keep going out of sync with the ones on your remote machine.

rsync your project valgrind it via a simple make target -> perfect

Now this worked just perfect for me. Here is the gist:

Here is a sample Makefile which contains only the targets relevant to run valgrind:

VFLAGS = --track-origins=yes --tool=memcheck --leak-check=yes --error-exitcode=1

    ssh udesktop 'rm -rf tmp/ee'
    rsync -ra -e ssh --exclude '/.git' --exclude '/bin' --exclude '/deps/**/*.o' --exclude '/build' . udesktop:tmp/ee

grind: $(TESTS)
    set -e; for file in bin/test/*; do echo "\n\033[00;32m+++ $$file +++\033[00m\n" && valgrind $(VFLAGS) ./$$file; done

rgrind: rsync
    ssh udesktop 'cd tmp/ee && make clean && make grind'

Note that udesktop is the remote machine that I configured in ~/.ssh/config:

host udesktop
  User my_username
  Port 3333

Now running make rgrind takes just a few seconds to give you the much wanted valgrind report:


In case you want a more detailed report you could add the following targets to your Makefile:

grind-report: $(TESTS) 
    for file in $^; do \
        echo "\n \033[00;34m+++ $$file +++ \033[00m\n" && \
        G_SLICE=always-malloc G_DEBUG=gc-friendly \
        valgrind $(VFLAGS) -v --num-callers=40 --log-file=valgrind.log ./$$file; \

rgrind-report: rsync
    ssh udesktop 'cd tmp/ee && make clean && make grind-report'
    scp udesktop:tmp/ee/valgrind.log .
    cat valgrind.log

To see a full example, please review either thlorenz/ee.c or thlorenz/sync-stream.c and have a look into the file.

Dealing with make warnings about timing issues

If your target machine's clock is running behind the one on your local machine, make will warn you that the .c files are newer than the current time. You can easily fix this by managing the time on your remote machine as explained here for ubuntu.

Continuous Integration with Travis

You've set things up this far, you might as well have these tests run every time you push to your repository. Assuming you installed the travis-ci hook, adding this simple .travis.yml to your project will do just that.

language: c
  - clang
  - sudo apt-get -qq install valgrind
script: make CC=$CC grind