Illegal Functions



When you are using OmniObjectAlloc, you are making a commitment to report all allocation events. Typically, this entails simply using the YellowBox APIs for all of your memory allocation needs. You should NOT use any of the underlying BSD or Mach primitives if you can possibly avoid it. If you cannot, you should avoid mixing the two (for example, allocating memory with NSZoneMalloc() and the freeing it with free() is a sure way to confuse OOA.

At Omni, we have started disallowing any use of the Mach or BSD APIs by default. To implement this policy, I wrote two scripts. The first, findmo, will take a list of directories as arguments and will print out a list of all the Mach-O files in those directories. The second, badfunctions, will take a list of Mach-0 files as its standard input and will search them for reference to any of the following:


malloc() use NSZoneMalloc()
free() use NSZoneFree()
realloc() use NSZoneRealloc()
calloc() use NSZoneCalloc()
vm_allocate() use NSAllocateMemoryPages()
vm_deallocate() use NSDeallocateMemoryPages()
vm_copy() use NSCopyMemoryPages()
map_fd() use -[NSData initWithContentsOfMappedFile:]

These two scripts are included in the OmniObjectAlloc distribution (in OmniObjectAlloc.app/Resources) to help you eliminate any non-YellowBox memory allocation from your applications. OmniObjectAlloc will print out messages when it thinks it has detected use of non-YellowBox API (for example, if it gets a NSZoneFree() request for a block that it doesn't know about).

One interesting note here is that there is currently no good alternative to map_fd (the Mach routine to map a file into a block of virtual memory). This function implicitly allocates a block of virtual memory that should later be deallocated using vm_deallocate() (or better, NSDeallocateMemoryPages()). But no allocation event is generated describing this new block of memory.

The OOA client framework patches the method denoted above to fake an event that makes it look like NSAllocateMemoryPages() was called. This keeps OOA from getting confused when you deallocate memory for mapped files, and more importantly, it lets you know when your VSIZE is being artificially inflated with mapped file memory.