iPhone: Testing your Application with Valgrind

24 Dec 2008, 15:39 PST

On other platforms, I've found valgrind to be indispensable when it comes to discovering and fixing bugs. With Greg Parker's port of valgrind for Mac OS X now available, it's now possible to test your Mac and iPhone applications with valgrind.

Valgrind does not support ARM, but it is capable of executing i386 binaries built against the iPhone Simulator SDK. The only difficulty is that you can't run valgrind from the command line -- GUI iPhone Simulator binaries must be registered and run by Xcode, which uses the private iPhoneSimulatorRemoteClient framework to start and stop Simulator sessions.

To work around this, I wrote a small "re-exec" handler in my application's main(). It looks like this:

#define VALGRIND "/usr/local/valgrind/bin/valgrind"
 
int main(int argc, char *argv[]) {
#ifdef VALGRIND_REXEC
    /* Using the valgrind build config, rexec ourself
     * in valgrind */
    if (argc < 2 || (argc >= 2 && strcmp(argv[1], "-valgrind") != 0)) {
        execl(VALGRIND, VALGRIND, "--leak-check=full", argv[0], "-valgrind",
              NULL);
    }
#endif
  
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"PeepsAppDelegate");
    [pool release];
    return retVal;
}

To enable this code, I added a 'valgrind' build configuration to my project which defines VALGRIND_REXEC. After switching to the valgrind configuration, my application will run in the Simulator, under valgrind:

[Session started at 2008-12-24 15:27:47 -0800.]
==38596== Memcheck, a memory error detector.
==38596== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.

Running our code under valgrind has greatly facilitated the resolution of otherwise difficult to find or entirely unknown bugs.