Take the 2-minute tour ×

Due to seeing random memory crashes in my iOS program, I decided to use Valgrind to help root out the problem, as they have a port that runs on the 32-bit mac OS X. I followed the instructions in this web page to set up Valgrind on the iPhone simulator here:


However, although I can get the program to compile in the iOS simulator, and the preprocessor flags set, I could not get Valgrind to actually run my program. It always quits with the following error:

valgrind: /Users/megahub/Library/Application Support/iPhone Simulator/4.2/Applications/6FD1FFF3-0EFB-4D81-A95A-F02E0AA9095E/QuamStockAdHoc.app/QuamStockAdHoc: cannot execute binary file

cannot execute binary file

How can I resolve this problem? I've verified that the executable is present at that path, because I can run it without Valgrind in the simulator.

share|improve this question
What does "file" return to you? (should be something like "Mach-O executable i386", if that's not the case you compiled for the wrong platform) –  Dunkelstern Feb 16 '11 at 14:32
Where can I find the return information? –  futureelite7 Feb 17 '11 at 1:33
The simulator has changed pretty radically from release to release, including the way binaries works. I'd wager some good money that valgrind isn't going to work with it without also porting valgrind to the simulator (which may be nearly impossible as well). The binaries run in the simulator don't work quite like regular Mac OS X binaries.... –  bbum Feb 17 '11 at 8:47

3 Answers 3

up vote -3 down vote accepted

Why use valgrind in the first place? You have NSZombie and friends plus Instruments with its leak checker.

How to set up:

  1. Go to Xcode, select your built product (the .app), doubleclick on that. (in Xcode 4 Menubar->Product->Edit Scheme)
  2. Add a new environment variable named "NSZombieEnabled" and set the value to "YES"

Alternatively for more control:

  1. Create a new file in your home directory named ".gdbinit" (note the dot in front) with the following content:

    fb -[NSException raise]
    fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
    fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
    set env MallocHelp=YES
    set env NSZombieEnabled=YES
    set env NSDeallocateZombies=NO
    set env MallocCheckHeapEach=100000
    set env MallocCheckHeapStart=100000
    set env MallocScribble=YES
    set env MallocGuardEdges=YES
    set env MallocCheckHeapAbort=1
    set env CFZombie 5
    fb -[_NSZombie init]
    fb -[_NSZombie retainCount]
    fb -[_NSZombie retain]
    fb -[_NSZombie release]
    fb -[_NSZombie autorelease]
    fb -[_NSZombie methodSignatureForSelector:]
    fb -[_NSZombie respondsToSelector:]
    fb -[_NSZombie forwardInvocation:]
    fb -[_NSZombie class]
    fb -[_NSZombie dealloc]
    fb szone_error

If you run your App in a standard debugger now it halts on every memory error. You can see if it works if a long memory debugger help text is displayed if you start the debugging and watch the console.

share|improve this answer
Yes, but valgrind is also a useful tool. Just want to figure out how to make it work. –  futureelite7 Feb 17 '11 at 1:36
Not an answer to the question and there are lots of things that valgrind can detect that this stuff can't. –  smparkes Dec 2 '11 at 20:16
all possible, but to find extended memory errors in an app instruments is the tool of choice. Perhaps there are errors that need valgrind, but I think using the right tool for the right thing is the better and less stressful way to do things ;) –  Dunkelstern Dec 5 '11 at 20:10
valgrind is COMPLETELY DIFFERENT from Instruments. Instruments often fails to find even the things its supposed to find (lots of Instruments is still very newly-written for iOS, and doesn't work properly yet). –  Adam Apr 17 '13 at 13:48

The compiler default is 64-bit (assuming you have a 64-bit machine), but valgrind does not yet officially support 64-bit executables on Mac OS X,(As per my knowledge, I might be wrong). The file command on your executable should report "Mach-O executable i386". Also be sure that you have 32-bit versions of all the libraries you are using.

share|improve this answer
Megahubs-iMac-2:QuamStockAdHoc.app megahub$ file QuamStockAdHoc QuamStockAdHoc: Mach-O executable i386 The file command reports that it is a Mach-O executable already. –  futureelite7 Feb 21 '11 at 1:42
Wrong. The iPhone simulator uses 32bits binaries in order to be closer to the actual hardware which uses a 32bit processor. –  Ecco Aug 2 '13 at 14:07

There may be other things that trigger this message, but a common cause is trying to use valgrind on a 32 bit executable when it has been compiled to only run on 64 bit executables. (MacPorts as of this writing does that on 64 bit OS builds). This isn't specific to the simulator: trying to valgrind any 32 bit app will produce this.

A native install from source of valgrind with no extra arguments to configure will work on either 32 or 64 bit executables.

This doesn't get me all the way to being able to run valgrind within the simulator. Not yet ...

Follow up:

Getting the width right doesn't get you too far. As mentioned somewhere else, what's really required is porting valgrind to the simulator runtime. It needs to use all the platform SDKs just like the target app does.

Turns out, this is possible. Not easy, and I'm not sure how stable it is, but possible. I think I'll talk to the valgrind folks about whether this can be cleaned up somehow and made a supported port/target.

When it works, it's beautiful:

  char* p = new char[10];
  delete p;
  *p = 12;

turns into

==49084== Invalid write of size 1
==49084==    at 0x6C536: -[AppDelegate application:didFinishLaunchingWithOptions:] (app_delegate.mm:813)
==49084==    ...
==49084==  Address 0xc6cca70 is 0 bytes inside a block of size 10 free'd
==49084==    at 0xC51041: free (vg_replace_malloc.c:430)
==49084==    by 0x6C52F: -[AppDelegate application:didFinishLaunchingWithOptions:] (app_delegate.mm:812)
==49084==    ...

Pretty symbols and line numbers. Wonderful.


I got to the point where valgrind would barf on Apple's sqlite3 dylib. I'm not 100% sure why but I think it's because Apple's version of sqlite3 has some mach calls that valgrind doesn't cover. So I never got it to work in total on my app. I raised the topic on the valgrind list but it didn't raise any interest. I'd still like to get it to work, but it's not going to happen too soon ... at least not by me.

Hmmm ... wonder if I can raise any interest at WWDC ...

share|improve this answer
I doubt it will work with blocks and NSOperation queues, but please tell me if it does and how it works if you get to it. I am a fan of instruments though as it's just the way it was thought out and I for my part was able to find all bugs with it easily. Nonetheless valgrind is a really cool tool, so why not use it if it's appropriate. –  Dunkelstern Dec 5 '11 at 20:07
valgrind doesn't care about blocks or queues. It operates at the machine code level which is independent of all that stuff except to the extent that they interact with threads and stacks. What valgrind does care about is low level system calls, so that it can record how memory values interact with the kernel and the support for mach in valgrind isn't the strongest. –  smparkes May 25 '12 at 14:54
I was suggesting NSOperation queues because they use Grand Central Dispatch which seems to work different than normal threads on kernel level, see comments.gmane.org/gmane.comp.debugging.valgrind.devel/10439 –  Dunkelstern May 30 '12 at 8:01
Great link. Thanks. I'd never heard of workqueue threads. Seems to be yet another case (and a particularly subtle one) where the mach kernel interface is obscure enough that it's hard to teach valgrind how to cope. Even in my early checking, I found comments in the valgrind mach support that said they weren't covering/hadn't figured out all of the mach kernel semantics (for something related to vm, as I recall). –  smparkes May 30 '12 at 14:55
I was able to get valgrind working on the iOS 7.1 simulator (the 8.0 sim appears to emit as-yet unknown sys calls). I'll contact the valgrind folks with a fix for the wqthread_hijack function under DARWIN_10_10. Also: I had to build valgrind manually, passing -isysroot "<ios8 sdkroot>" as well as changing the -mmacosx-version= flag the iPhone simulator equivalent "-mios-simulator-version-min=7.0" Finally: you must disable anything that could play sound. There are DSP instructions that valgrind does not support in the iOS HAL code. –  Mark Pauley Dec 7 at 6:13

Your Answer


