taylorbarstow.com

Earning Some Cocoa Chops

New APIs are hard!  Throughout my life as a programmer, I’ve told people that once you master a few languages, learning new ones becomes much easier.  But learning to go beyond the language and develop something complex on a new platform is a different beast.

My new challenge is Cocoa.  I’m learning Objective-C and the Cocoa (NeXTSTEP) framework to implement a killer solution for graphic designers.

Today, I picked up some chops when it comes to debugging.  One of the trickiest things about C is proper memory management, and this carries over to Objective-C.  The syntax is simplified, but getting the logic right is just as tough.  (Cocoa programmers: obviously I’m talking about traditional retain/release stuff here, not garbage collection).

I spent six hours tracking down a memory management bug.  Some object was being over-released, causing my program to crash.  I had no idea which object it was, though I had a theory, and I wasted time on it.  I didn’t know what to Google for (new platforms are hard), but eventually I landed on it.

The solution? A combination of NSZombieEnabled and MallocStackLogging. NSZombieEnabled proxies release messages.  It will never set a retainCount to zero.  Instead, it logs a message containing the process ID and memory address of the object being over-released.

Conveniently, MallocStackLogging lets you inspect the stack trace up to the malloc call for a given PID and memory address.  Once you find the malloc call, you’ve found your object.

Do I wish I hadn’t spent six hours on this (plus writeup)?  No way—it’s struggles like these that help me master a new environment. The best way to learn a new city? Go out and get lost, then find your way back again. The best way to learn a new platform? Hit a wall and learn how to climb over it.

Feeling the Love

I just received an amazing response to a question that I had posed to Apple’s unix-porting mailing list.  I was having a problem compiling bspatch (there were some missing type declarations), and had suggested one potential solution.  Terry’s response:

No, it’s also missing an off_t definition.
You definitely need:

======
*** bspatch.c.org       Mon Aug  4 14:58:06 2008
— bspatch.c   Mon Aug  4 14:58:09 2008
***************
*** 28,33 ****
— 28,34 —-
__FBSDID(”$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $”);
#endif

+ #include <sys/types.h>
#include <bzlib.h>
#include <stdlib.h>
#include <stdio.h>
======

The code was written incorrectly assuming promiscuous headers. The FreeBSD headers pollute the POSIX namespace with symbols they are technically not permitted to define in scope, as a side effect of how the headers are organized. They would fail The Open Group VSX/VSU header tests for UNIX conformance. You basically need to include a standard header for the different types you end up using in the code.

See also:

<http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/types.h.html>

PS: The u_char is a side effect (BSD) type, and is pulled in only because of historical use, and the fact that _DARWIN_C_SOURCE is a superset of _POSIX_C_SOURCE/_XOPEN_SOURCE; this may end up changing in some future release. The correct type is most likely either simply “unsigned char”, or if you wanted to be more correct and used a sized type so the structure packing doesn’t change on you, “uint8_t” after “#include <stdint.h>”.

Wow.

He could have said, “You need to #include <sys/types.h>” and been done with it.  Instead, he explained the why of the situation, and thus I learned:

  • if you have any errors about missing type declarations, make sure types.h is included
  • FreeBSD has a messy implementation of the POSIX types system, so porting from FreeBSD to other OSes will often give type errors
  • Apple really cares about being a platform company, so they take care of their developers

This illustrates what good can happen when a company’s vision lives and breathes.  When your vision lives and breathes your company exudes it from every orifice.  This, it seems, is but one of the many aspects of company balance that comprise success.

Thanks Apple, you taught me a lesson today - in more ways than one.

Binary Diff

I always thought diffs were only really useful for text content.  Then I finally googled “binary diff”, and I discovered something amazing: there are some really good binary diff algorithms out there!

This is exciting for me, since I’m basically working on a network file system that will have to move a lot of deltas across the wire.

As a test run, I diffed the Photoshop file for my business card with Adrian’s.  Each file is a little over one megabyte.  The difference between them?  Only 22KB.  Rockin’.