2010

2009

2007

2006

2005

Nasty hacking with 64-bit Objective-C

Entry published sep 10 2009

If you’re loading code dynamically and using an unsupported API under Cocoa 64bit, you’ll be greeted with this unpleasant surprise:

9/7/09 2:34:06 PM   Mail[8641]  MailTest.mailbundle failed to load. The error was:
Error Domain=NSCocoaErrorDomain Code=3588 UserInfo=0x100563840 "The bundle “MailTest” couldn’t beloaded."

After many hours of slamming my head against the desk, and help from others (namely Erik Hinterbichler, I’ve figured out how to get around this error. Why would you want to do this in the first place? Well, it’s useful for creating addons to closed source products like Mail.app and Safari. The usual procedure involves dumping the headers for the app using class-dump, determining how to swizzle your code in, and finally figuring out how to load your code into the app.

With the switch to 64bit, Objective-C has a new dynamic loader that pays attention to symbol visibility. The 32bit loader didn’t, and would allow your code to bind to any symbol in the app. With the 64bit loader, only symbols that are explicitly exported are available for dynamic binding. As a result, nearly all the symbols in an app like Mail.app aren’t exported for binding. If you do try to bind, you’ll see that error message above.

So what’s the trick? Never reference any of the symbols directly! Instead you’re going to us NSClassFromString along with the Objective-C runtime methods available from the header <objc/runtime.h>

Here’s how I now set the super class for a Mail.app plugin:

+ (void) initialize {
    class_setSuperclass([self class], NSClassFromString(@"MVMailBundle"));
    [MattsMailBundle registerBundle];
}

Notice, this is done in the initialize class method, and no Mail.app symbols (in this case MVMailBundle) are referenced directly.

Hope that helps, happy hacking!

4 comments category: cocoa
. o .

→ 13 more things that don't make sense

Entry published sep 03 2009
. o .

→ Urinal protocol vulnerability

Entry published sep 02 2009
. o .

→ The bar for success in our industry is too low

Entry published sep 02 2009
. o .

Mini book review on Making of the Atomic Bomb

Entry published aug 31 2009

Posted it to my reading section. Take a look. Summary: If you’re into physics go buy it, it’s an excellent book.

1 comment category: general
. o .

→ The Wysiwym Markdown Editor

Entry published aug 31 2009
. o .

→ Top 10 tips to a new django developer

Entry published aug 31 2009
. o .

A hacker's easy dinner: Vegetarian Tacos

Entry published aug 13 2009

I’m adding some simple recipes that are, potentially, useful for fellow computer hackers. Most of these recipes are great for getting dinner out of the way, without resorting to a fast food trip.

My first recipe: tacos made with a vegetarian ground beef substitute. I’m not a vegetarian, but the soy protein substitute is faster and easier to make. I usually grab a few bags of ground beef substitute and keep them in the freezer for when I want to throw something quick together.

Ingredients

  • 2 - 3 Tbsp Olive Oil
  • Small onion
  • 2 cloves garlic
  • 1 bag Morningstar Grillers Crumbles OR Boca Ground Crumbles
  • 1/4 tsp Cayenne Pepper
  • 1/2 tsp Chili Powder
  • Salt & Pepper
  • Corn tortillas
  • Toppings (cheese, salsa, tomato, lettuce, etc…)

Directions

  1. Heat up a skillet with the Olive Oil.
  2. Dice the onion and add it to the skillet
  3. While the onion is cooking, mince the garlic and add it
  4. Cook the onion and garlic until the onion looks fairly translucent and it’s soft, now pour in the bag of crumbles
  5. Stir around the crumbles, and add the cayenne pepper, chili powder and toss in some salt and pepper. If the pan is really dry, add some more oil
  6. In less than 5 minutes the crumbles should be ready, meanwhile heat up corn tortillas with the stove or microwave
  7. You’re done! Add some toppings I like to eat my tacos with some cheese, tomatoes, and jalapeños. Try mixing it up for some variety

It’s pretty damn tasty, and very easy. Now back to coding!

4 comments category: food
. o .

Recent Reading List

Entry published aug 10 2009

I put a little reading list together on this site where I can make small comments on recent reading and whether or not I recommend the book.

Take a peek as I get started with my list

0 comments category: general
. o .

MailCore 0.2.7

Entry published aug 10 2009

I’ve finally gotten around to releasing a new version of MailCore… Since my last release a few patches have been submitted, special thanks to those that sent in patches.

MailCore is now being used in a few iPhone apps (maybe someone can submit a patch to make MailCore buildable on the iPhone?), and I’m currently using it for an unannounced product (and no, not Kiwi, something else I’ve been working on).

Here is a list of the major changes:

  • Fixed a memory leak found by Stefano Barbato where mime structures weren’t autoreleased when returned
  • Added a new method to CTCoreMessage that can be used to init from a string
  • Added proper decoding of unicode characters, w/ test (patch from Julián Romero)
  • Updated the examples to work with the latest API
  • Fixed a issue with CTCoreMessage where fields were being freed twice

Grab a prebuilt framework here or grab the source from BitBucket

1 comment categories: general programming, cocoa
. o .

Why Not the Best?

Entry published aug 02 2009
“I had applied for the nuclear submarine program, and Admiral Rickover was interviewing me for the job... Finally, he asked me a question and I thought I could redeem myself. He said, "How did you stand in your class at the Naval Academy?" ... I swelled my chest with pride and answered, "Sir, I stood 59th in my class of 820!" I sat back to wait for the congratulations - which never came. Instead, the question: "Did you do your best?" I started to say, "Yes, sir," but I remembered who this was ... I finally gulped and said, "No, sir, I didn't always do my best." He looked at me for a long time, and then finally turned his chair around to end the interview. He asked one final question, which I have never been able to forget, or to answer. He said, "Why not?"”

— Jimmy Carter, Why Not the Best?

. o .

Rickover's psychological exam

Entry published aug 02 2009
“SHRINK: Do you like your work? RICKOVER: No. SHRINK: Do you like people? RICKOVER: No. SHRINK: Are you happy? RICKOVER: No. [Shrink pauses, to figure out where to go form here] RICKOVER: Are you going to ask any more damn fool questions? SHRINK: No. ”

— Theodore Rockwell, The Rickover Effect

. o .

→ Tail mode in emacs

Entry published aug 01 2009
. o .

→ A short history of btrfs

Entry published aug 01 2009
. o .

→ My Thoughts on NoSQL

Entry published jul 21 2009
. o .

→ How SQLite Is Tested

Entry published may 30 2009
. o .

→ Why Darwin Failed

Entry published may 25 2009
. o .

→ A re-introduction to JavaScript

Entry published may 11 2009
. o .

→ Succinct overview of Javascript

Entry published may 11 2009
. o .

→ Oh Apple

Entry published may 11 2009
. o .

→ New Mercurial GUI for OS X

Entry published apr 30 2009
. o .

→ Use Mercurial with a Git Repository

Entry published apr 30 2009
. o .

A sample Mercurial bookmark workflow

Entry published apr 01 2009

Bookmarks were, for me, the missing piece in Mercurial. Before bookmarks,there wasn’t an easy way of working on multiple changes simultaneously, something I do alot. Usually, I fix a bug or add a feature and put it up for review. While the code is under review I start working on something else. The existing options don’t nicely solve this problem:

  • Mercurial branches can’t be destroyed. Once you create a branch, it’s stuck and global. I don’t want to clutter everyone with a bunch of branches.

  • I can’t easily clone another copy of the repository. My emacs config is set to a specific directory. and we have environment variables that make it a pain.

  • Mercurial Queues come the closest to solving the problem, but are also a no go. Lets say, I create a new patch in the queue, and then create a second one. Due to how queues work, patch one is the parent of patch two. This is a problem because it doesn’t play nicely with software like Review Board.

  • There is also the shelf extension, but I believe you can only shelve one thing at a time. I don’t remember why else I didn’t use this, but I know I didn’t like it.

Mercurial bookmarks come to the rescue and let you create a bookmark for each change. (Initially I couldn’t get bookmarks to work, so I hope I will save others from similar trouble. I can’t remember what I was doing wrong but props to Augie Fackler for showing me how to properly use bookmarks.) So here’s a sample workflow.

Let’s say we have to fix a bug. We start by making a bookmark:

hg book bugX

Typing hg book will show us our current active bookmarks:

* bugX                      0:2473879fcde9

Now, code, code, … code and commit:

hg commit -m "Bug fix #X"

We dump that change for review:

hg out -p > ~/bug_x.patch

While a coworker makes sure I didn’t break anything with a code review, I’d like to get started on a different change. So let’s go back to the parent changeset, since we don’t want to build our changes on top of the fix, we create another bookmark.

hg up 0 # rev number is 0 just in this example
hg book cool_feature

And now hg book will show two bookmarks

* cool_feature              0:2473879fcde9
  bugX                      1:94b0bd2a03ae

More coding … and during the review my coworker found a flaw in my bug fix, I want to get that pushed out right away, so let’s checkpoint, update the bug fix and come back to this later.

hg commit -m "cool_feature checkpoint. Doesn't fully work"
hg up -C bugX

Now we are back at bugX, so I can do the necessary changes, commit that, and create a new patch. This time I need to specify which bookmark to use for creating the patch, since we have two.

hg up -C bugX
# Make our changes
hg commit -m "Updated bug fix #X"
hg out -r bugX -p > ~/bug_x.patch

Now we can switch back to our work on that cool new feature:

hg up -C cool_feature

If we look at the log, we can see the two heads we’ve created:

@  changeset:   3:750736b7f1a7
|  tag:         tip
|  tag:         bugX
|  parent:      1:94b0bd2a03ae
|  user:        Matt Ronge <mronge@xxxxx.com>
|  date:        Wed Apr 01 22:13:10 2009 -0500
|  summary:     Cleaned up bug #X
|
| o  changeset:   2:597b5f702706
| |  tag:         cool_feature
| |  parent:      0:2473879fcde9
| |  user:        Matt Ronge <mronge@xxxxx.com>
| |  date:        Wed Apr 01 22:10:38 2009 -0500
| |  summary:     cool_feature checkpoint. Doesn't fully work
| |
o |  changeset:   1:94b0bd2a03ae
|/   user:        Matt Ronge <mronge@xxxxx.com>
|    date:        Wed Apr 01 20:06:45 2009 -0500
|    summary:     Bug fix #X
|
o  changeset:   0:2473879fcde9
   user:        Matt Ronge <mronge@xxxxx.com>
   date:        Wed Apr 01 20:03:54 2009 -0500
   summary:     Commit 1

As you can see, bugX and the cool feature share the same parent, but are otherwise two independent branches of development. Let’s finish up work on the feature..and we’ve gotten permission to commit the bug and feature. So let;s merge them and push the result out.

hg commit -m "Finished feature"
hg merge bugX # merge bugX into the current line of development of cool_feature
hg commit -m "Merged"
hg push

And now we are done. That was a bit pedantic to go through the entire workflow, but my hope is that putting in each step will help others get acquainted with bookmarks. It’s also interesting to see the final graph:

@    changeset:   5:9bd7038876ba
|\   tag:         cool_feature
| |  tag:         tip
| |  tag:         bugX
| |  parent:      4:f80dcce7e0da
| |  parent:      3:750736b7f1a7
| |  user:        Matt Ronge <mronge@xxxxx.com>
| |  date:        Wed Apr 01 22:24:09 2009 -0500
| |  summary:     Merged
| |
| o  changeset:   4:f80dcce7e0da
| |  parent:      2:597b5f702706
| |  user:        Matt Ronge <mronge@xxxxx.com>
| |  date:        Wed Apr 01 22:20:41 2009 -0500
| |  summary:     Finished feature
| |
o |  changeset:   3:750736b7f1a7
| |  parent:      1:94b0bd2a03ae
| |  user:        Matt Ronge <mronge@xxxxx.com>
| |  date:        Wed Apr 01 22:13:10 2009 -0500
| |  summary:     Cleaned up bug #X
| |
| o  changeset:   2:597b5f702706
| |  parent:      0:2473879fcde9
| |  user:        Matt Ronge <mronge@xxxxx.com>
| |  date:        Wed Apr 01 22:10:38 2009 -0500
| |  summary:     cool_feature checkpoint. Doesn't fully work
| |
o |  changeset:   1:94b0bd2a03ae
|/   user:        Matt Ronge <mronge@xxxxx.com>
|    date:        Wed Apr 01 20:06:45 2009 -0500
|    summary:     Bug fix #X
|
o  changeset:   0:2473879fcde9
   user:        Matt Ronge <mronge@xxxxx.com>
   date:        Wed Apr 01 20:03:54 2009 -0500
   summary:     Commit 1
5 comments category: software
. o .

→ Common workflows in different DVCS's

Entry published mar 31 2009
. o .

→ Automated testing webapp testing with Python

Entry published mar 27 2009
. o .

→ Short overview on distributed DB's

Entry published mar 27 2009
. o .

→ Scaling Lucene & Solr

Entry published mar 15 2009
. o .

→ Stunning explanation of the credit crisis

Entry published feb 20 2009
. o .

→ IMAP rant from sup developer

Entry published feb 15 2009
. o .

Cocoa development and testing

Entry published feb 15 2009

I’m not sure why, but the Cocoa development community doesn’t seem to be into unit testing. Or perhaps, I’m misreading the community and it’s mainly Apple that doesn’t push unit testing hard enough.

It wasn’t until recently that Xcode even had unit test support, sure, you could use 3rd party frameworks, but it wasn’t built in. It’s unacceptable for testing not to be a high priority, and I’m not sure why Apple waited so long to bake it in. Even now you have to jump through hoops to get the debugger working with unit tests. From my personal experience as an intern at Apple, both teams I was on did not make significant use of automated tests while developing. Sure, there were QA teams, but unit tests weren’t present. Apple just doesn’t get unit testing (thankfully there are a few on the inside who are test infected, like Chris Hanson, who as a member of the Xcode team is probably responsibly for the unit test support in Xcode).

Xcode now has support for unit tests, and Apple did put out a guide on unit testing. So the situation is getting better, but not ideal. In comparison, the Java community really gets testing, and has a whole host of useful tools (Java does have many other problems, but at least testing isn’t one of them). Tools like test coverage analyzers and mock object frameworks. These tools should be included with Xcode by default.

Maybe the next version of the dev tools will include OCMock, and GUI support for GConv. Or has the situation gotten better and I haven’t noticed?

0 comments category: cocoa
. o .

→ New email client Postbox

Entry published feb 13 2009
. o .

New blog software, new server

Entry published feb 11 2009

Welcome to my refreshed blog!

I hadn’t noticed until recently that I haven’t updated since 2007, yikes. But, its back and here to stay. I’ve moved my VPS to Linode which is cheaper and much more powerful then my previous one. Along with the switch to the new VPS, I’ve changed from Wordpress to a custom Django application originally called CX which was developed by Jesper Noehr, one of the guys behind BitBucket. Since I don’t like PHP, I really like Python, and my previous Wordpress install was hacked; I decided to move to CX and hack it up. The code is quite nice, so it was easy to make modifications. I added support for Atom feeds, source code highlighting, and layout changes. The layout is a bit rough, but it works for now.

If you’re interested in my changes, you can take a look at the fork of CX I created CXR

1 comment category: general
. o .

→ Tips for working on a personal software project

Entry published feb 11 2009