Archive for January, 2008

Silly Hack of the Day: Mount the Obj-C Runtime as a Filesystem

Thursday, January 10th, 2008

Update: CocoaHacks was quite a bit of fun. Not only did I demonstrate the rather silly little hack, but I ran it fully garbage collected. With one simple change (that should be in the next release), the MacFUSE framework works just fine with Garbage Collection enabled!

The best compliment came from Amit Singh; something along the lines of “That is absolutely the strangest filesystem I have seen.”

In any case, my little hack repository has been updated to be GC only. retain/release/autorelease/dealloc are dead to me (in this project, anyway).

If you want to build MacFUSE with GC enabled, simply set Objective-C Garbage Collection to “Supported” in Xcode in the MacFUSE framework project’s build settings.

Browsing Classes_tn.png

At left, is a screenshot of the Finder browsing the Objective-C classes active in the runtime of a little Cocoa app that I wrote this evening.

The little app is called RuntimeFS and it contains a simple bit of code that traipses through the Objective-C runtime and collects information about the Objective-C classes encountered. This information is then barfed up by the elegantly simple delegate like API required by MacFuse to create a filesystem.

Let me restate that: MacFuse kicks ass. The Objective-C API is trivially easy to use. Trivially easy. I implemented this little hack in less than two hours, not having looked at the MacFuse API before. Nor did I read the docs; just looked at this example and one header file. I have implemented filesystems in a couple of different languages. Filesystems are hard. Or was. Not anymore.

I dropped the source code in the “Silly” directory of my public SVN repository.

Because, really, this is quite a silly hack. And hack it is — it doesn’t crash, but that is about all the quality assurance analysis I have done.

Free as in “MIT License” free. Have fun. I’m accepting patches, of course.

Future Stuff

If I were to go anywhere with this, the first thing I would do would be to move the subclasses into a subdirectory and then add other subdirectories to contain additional data.

Specifically, I would add directories like -1- Instance Variables, -2- Class Methods, -3- Instance Methods, -4- Subclasses, -5- Documentation (or something), etc…

The naming convention serves two purposes. First, it sorts nice like. Secondly, the names are invalid as class names and, thus, it makes handling the metadata vs. class directories trivially easy while also eliminating potential namespace conflicts.

Yes, The Bay Area Has Weather

Saturday, January 5th, 2008
Storm Damage

For 9 to 10 months out of the year, the bay area has exactly one kind of weather. Cool evenings, warm to hot days, little to no humidity.

For the other 2 months, it is mostly just the occasional rain shower, colder temperatures, and the occasional freezing temperature.

Of course, like everywhere else, the local news folk are all about senstionalizing the crap out of the weather as much as anything else. Which leads to the ridiculous. I remember when I moved out to the bay area in the middle of June and all the news stations were, like, “OMG! STORM OF THE CENTURY! AAUUGH!! FIRE & BRIMSTONE!!!”.

Turned out to be a bit of rain and some lightning in the mountains in June.

Storm Damage

As laughable as “severe weather” in the bay area most often is (OMG! IT’S HOT! OHNOESRAIN!), the bay area does actually have weather. And seasons, too (we had awesome fall colors this year).

And weather we just had!

Read the rest of this entry »

Objective-C: Using Instruments to trace messages-to-nil

Friday, January 4th, 2008
In Action_tn.png

In Leopard, Apple added a new tool to the developer tool suite called Instruments. It is a timeline based debugging and performance analysis tool. With a full suite of tools to analyze all kinds of dimensions of performance, correlating all data onto a timeline that can be inspected and navigated at will. And it remembers prior runs so you can compare results before and after changes.

And it fully consumes dtrace.

Clicking through the screenshot at right will show a run of Instruments with a single analysis instrument active.

I created a custom instrument that encapsulates the dtrace script I discussed in Objective-C: Using dtrace to trace messages-to-nil.

I ran the resulting instrument against TextEdit.

What can’t be conveyed by that screenshot is exactly how “live” the data can be examined. You can click and drag on the timeline to select a subset of the run, details of the selected instrument are shown in the table in bottom right, and any given row can be selected to show the backtrace active at the time the sample was taken.

I didn’t want to clutter up the screenshot with lots of data and, thus, didn’t demonstrate the awesomeness that is being able to relate data across multiple instruments, correlated by time.

That’ll be in the next Mac OS X / Software related post.

Click on through for an explanation with screenshots as to exactly how to convert the dtrace script to an instrument.

Read the rest of this entry »

Objective-C: Using dtrace to trace messages-to-nil

Thursday, January 3rd, 2008

Update: There are [at least] two different Objective-C messagers. objc_msgSend() and objc_msgSend_stret(). All of what is written here applies to both however objc_msgSend_stret() is the problematic one when it comes to messages to nil; it is the one used to return structures and, thus, the one that does not necessarily guarantee a zero return.

In my last post on the subject, Adrian Milliner posted a short dtrace script that would log the backtrace for all invocations of objc_msgSend where the first paramater — the target — was nil.

The script is as follows:


Once saved to a file (in this case objc-nil-trace.d, the trace can be applied to any running Cocoa process via:

sudo dtrace -s objc-nil-trace.d <pid>

The <pid> argument should, obviously, be the process ID of the process to be traced.

It works well enough and is certainly faster than a conditional breakpoint in GDB (likely, orders of magnitude faster), but it is far from a complete solution.

Read the rest of this entry »

The Blogging Family

Wednesday, January 2nd, 2008
Old Tree

My oldest sister, Ann, now has a weblog. It is called The Tombstone Chronicler (fixed) and she promises to clue us all in to the meaning of that title shortly.

I chose this particular photo for my post pointing to her weblog because she used a rather brilliant photo of the same tree as the header image on her weblog. We are definitely cut from the same cloth; “did you get a photo of the old tree?” being a common question.

That particular tree is in the valley behind our parent’s house and it has been hollow for a good 20 years now (15 years ago, three of my friends and I shared a bottle of Jack in that tree — back when you could climb into it without getting wet).

Next up? My mom has expressed interest in weblogging. She is a great photographer and writer. As well, mom is the Master of Foods.

We might even start a multi-author food blog of our own…

And my other sister, Carrie, could school us all on the intracacies of power distribution systems. Seriously. I have always been into electronics/electricity and I remember when she started calling to ask some basic questions about electricity to support some cases she was working on (she is lawyer). Then, a couple of years later, she was all, like, “What can you tell me about energy loss across out of phase high voltage distribution networks?” “Uh… huh… what? Nothing. What can you tell me?” Turns out, quite a bit.

Carrie hasn’t expressed much interest in Blogging. Yet.

Freaky Fly

Wednesday, January 2nd, 2008
Fly on Pencil

Roger caught this little freaky dude in our house.

We tossed it into the fridge for a while to calm the fly down.

And then we took it into the garage and let it slowly crawl around a pencil while I snapped some macro shots.

I had the camera settings all wrong, but I still managed to capture a bit of the essence of oddness of this fly.

Fly Head

Even still, the hexagonal grid of black spots on a yellow background of Dude Fly’s Eyes caught me by surprise at full scale in Aperture.

Nature rules. Roger let the fly go. A few minutes on his warm hand in the direct sun outside and Dude Fly was fully back into superfly mode.

Next time?


Make sure the damned ISO is at 100 or 200 (400 is noisy at low light on a Rebel XT). I hate it when I forget to reset it.

Remote trigger.

Try the make controller + external flash.

Get around to building a light box.

Objective-C: Logging Messages to Nil

Wednesday, January 2nd, 2008

This post will make this post useful.

Jim Correia had asked the lazytwitter how to log all method invocations against nil objects.

Some background:

Objective-C is a “nil eats messages” language. That is, if you invoke a method on an object reference that is nil, the runtime will eat the method. It is mostly invisible, only causing outright failures for certain return types that are larger than a pointer — structs, floats, doubles, etc… — at which point, the return value is undefined. Actually, the return value behavior for message to nil isn’t quite that simple.

Regardless of whether you think “nil eats messages” is the correct behavior, that it exists means that you’ll invariably be caught in a situation where a receiver is surprisingly nil. When this happens, it can be a pain to debug for a number of reasons.

Read the rest of this entry »

Objective-C: One Hack to Log Methods

Tuesday, January 1st, 2008

Jim Correia recently tweeted a query asking if it were possible to log all attempts to message through nil in Objective-C.

It is, but not through public API. But that isn’t the subject of this particular post (it’ll be the next post).

In the process of writing up a general solution to Jim’s query, it reminded me of a new feature in Objective-C 2.0 that can be a tremendously handy debugging and exploration hack.

Classes in Objective-C 2.0 can dynamically resolve methods by implementing one or both of the following methods:

+ (BOOL)resolveClassMethod:(SEL)sel;
+ (BOOL)resolveInstanceMethod:(SEL)sel;

The intended purpose of said methods is to allow code to provide an implemention of a method on demand. If the resolver methods can provide an implementation, it uses the function…

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);

… to add an implementation of the requested method to the class. If not, they return NO and the normal forward-or-fail mechanisms kick in.

You can easily create a proxy class that will log a method whenever it is invoked. The simplest form is as follows:

@interface LogEmAsTheyAreInvoked

@implementation LogEmAsTheyAreInvoked
+ (BOOL)resolveInstanceMethod:(SEL)name
    NSLog(@"Instance resolving %@", NSStringFromSelector(name));
    return NO;

+ (BOOL)resolveClassMethod:(SEL)name
    NSLog(@"Class resolving %@", NSStringFromSelector(name));
    return NO;

Of course, this is pretty much useless. Without an implementation of…

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;

… the runtime will rapidly decide that all viability is defunct, thus aborting your process. Even the most basic of services, such as allocation, cannot be handled directly. If you need to allocate an instance of the above, use something like:

class_createInstance(objc_getClass("LogEmAsTheyAreInvoked"), 0)

If you want to be particularly tricky, you could supply the proxied class’s instance size instead of the zero and then plug in the method implementations from the original class into the proxied class as each method is invoked. Behavior that tests the class hierarchy may be surprising.

On the slightly less tricky front, you could also create functionality like NSProxy and have the instance of LogEmAsTheyAreInvoked wrap — proxy — some instance of some class. Then it is just a matter of forwarding the method invocations, as desired (which could also directly be used for logging but lacks the nice & automatic “only invoked once” nature of the above methods).

In any case, a neat hack. One of many possible hacks in this vein and not the most general purpose of ’em. Potentially useful for debugging. Your mileage may vary.