The random rantings of a concerned programmer.

Archive for December, 2010

Punching Obj-C in the Face

December 14th, 2010 | Category: Random

So I have issues with CoreData. There’s enough ranting on it elsewhere, so I’ll summarize my key complaints with a short list:

  • CoreData isn’t threadsafe.
  • CoreData silently corrupts data on failures.
  • I didn’t write it, so it’s obviously a piece of shit.

Naturally, the first option is to write my own version of CoreData. Thankfully, there’s a whole documented runtime reference manual on how to interact directly with the Obj-C runtime API (which is all in C). In explanation, if you have the code –

[someObj someMethod:fuck who:you];

The Obj-C compiler basically translates this to something along the lines of:

Class *cls = someObj.isa;
Method m = class_getInstanceMethod(cls, "someMethod:who:");

if (!m) {
    /* Call forwarding functions (ala Ruby's method_missing) to forward the 
     * mis-sent message elsewhere; otherwise raise an 
     * "object-does-not-respond-to-selector" exception */
}

IMP imp = method_getImplementation(m);

/* imp is an X(*)(void*, SEL, ...) */
return imp(someObj, method_getName(m), fuck, you);

This is all wrapped up by objc_msgSend. These details are important because we effectively want to be able to define a data type as something like

@interface Fuck : BASEOBJ {
    NSString *dicks;
    NSArray *butts;
}

@property NSString *dicks;
@property NSArray *butts;
@end

And then have BASEOBJ automatically do everything for us. We can do this by injecting our own methods into the class definition with class_addMethod. If you recall, properties in Obj-C basically map to specially-named methods. Since we’re going to be dynamically injecting methods to our class instances, we have to please the type restrictions of the compiler by telling it we’re going to do this (it’s what CoreData does) with the @dynamic directive (instead of @synthesize):

@implementation Fuck
@dynamic dicks;
@dynamic butts;
@end

Then, during our initialization code, the properties can be enumerated class_copyPropertyList:

void injectProperties(Class cls) {
    unsigned int numProps;
    objc_property_t *propList = class_copyPropertyList(cls, &numProps);

    for (unsigned int i = 0; i < numProps; ++i) {
        objc_property_t prop = propList[i];

        const char *getPropName = property_getName(prop);
        class_addMethod
            ( cls
            , sel_registerName(getPropName)
            , (IMP) &getTypedProxy
            , "@@:"
            );

        const char *setPropName = strcat("set", capitalize(getPropName));
        class_addMethod
            (cls
            , sel_registerName(setPropName)
            , (IMP) &setTypedProxy
            , "v@:@"
            );

        free(setPropName);
    }

    free(propList);
}

The important bits to note here is that IMP is just a typedef for void*(*)(void*, SEL, ...) so we can cast basically any function to it. sel_registerName is the C-equivalent of NSSelectorFromString. getTypedProxy and setTypedProxy are two functions that implement the IMP interface and handle our getting/setting functions (I have them load/store values from Sqlite3, for example, but you can make them do anything). The last argument of class_addMethod is a convoluted clusterfuck -- it's basically the type signature of the IMP being passed in, encoded using Obj-C's bullshit method for RTT encoding. In this case, our methods are well-typed (get simply returns an Obj-C object; set takes an Obj-C object and returns void).

So, at this point we're reflecting on the defined properties of all the objects we want (we could take it a step further and check if the methods we're installing exist -- we could make it so we object inject for @dynamic properties which don't currently have a method assigned). We can do fucking anything from here. We're at the core of the runtime, and we're elbow-deep in it.

Fuck yeah.

Xcode just crashed.

7 comments

FreeBSD’s gmirror is a piece of shit

December 10th, 2010 | Category: Random

I do a lot of work on Fakku!, which is a weeaboo porn site. I swear the damn thing is cursed — it chews through HDDs at a daunting rate (though half of that, I suspect, is because the old host FDC, played dominos with the drives before installing them). Fakku’s main HDD (an SSD drive on top of that) blew up a month ago. Then a couple of weeks later the replacement drive they gave us also blew up. Naturally I was fucking through with their bullshit and migrated everything over to 100tb.

Instead of keeping with the monolithic-server-to-do-everything (8 cores and 16GB of RAM? fml), I decided it would be more cost effective to buy the shittiest servers they offer (4 core/8GB) and then balance the load between them. And then use gmirror to software RAID-1 the drives because restoring from backups takes bloody ages (separate datacenter, etc).

GUESS I FORGOT GMIRROR WAS A PIECE OF SHIT.

To install gmirror, you basically just load a kernel module in, create an array, then add the drives to an array. It’s kind of nice because you can create an array from an already-in-use drive, then add another drive to the array and it’ll work fine. This is helpful because sysinstall, FreeBSD’s installer, is an archaic piece of shit that only really supports plain vanilla installs on a single drive.

So I do all that jazz on the two machines and reboot them. One of them comes back up, the other one doesn’t. Fuck. So I read through the documentation, check the hardware specs, etc. The troubleshooting section has an “oh if it doesn’t work try compiling the kernel module in statically”. Guess what didn’t work. After dicking with the damn thing for a couple of hours I gave up on the second machine and just decided to run it without RAID.

Naturally, you’d assume having a RAID-1 setup would drastically increase your parallel read performance (and given we’re serving pornography, this is a pretty important figure). HAHA WELL YOU’D BE WRONG. Running a RAID-1 setup with gmirror does absolutely nothing to improve read throughput, which is fucking retarded.

But the fun doesn’t stop there.

A week after running the site on this setup, the RAID’d application server starts crashing randomly. It’s a soft crash — the machine is still running — you can ping it, you can do the first part of an SSH handshake — but anything involving disk I/O (validating SSH keys, requesting masturbation materials, etc) doesn’t work. Hard reboots don’t fix it — the data center tech has to go do something to it to power it back up (and they never tell you fucking anything). And there’s nothing in any fucking log about why it’s crashing. smartctl says the disks are peachy.

Whenever it’s brought back up, gmirror decides “SHIT A DRIVE IS DEGRADED MUST REBUILD THE ARRAY”. I’m not sure what the fuck it’s fucking doing but it’s probably related to the problem. God help you if the power cuts or anything bad happens while it’s rebuilding the array, too. I found the following advice on the FreeBSD mailing lists:

1) turn off gmirror
2) clear gmirror header on both providers
3) run fsck the other drive (not ad6, but the other used on mirror).
4) pray
5) after fsck will end it successfully (it should), create gmirror with the disk you checked
gmirror label
gmirror-name /dev/thedisk

6) reboot and start the system. should go well.
7) after system is running and not too much needing disk I/O, do
gmirror insert gmirror-name /dev/ad6
8) pray again, but with much less fear.
9) if gmirror will finish rebuild, all right.

Yeah… no thanks.

Fuck gmirror.

7 comments

(Untitled)

December 07th, 2010 | Category: Random

Sup guys.

I kinda missed having a place to post stupid shit that no one cares about, so I guess I’m gonna start doing that again.

Since the last post, I quit my job and got a new one working in California. After working there for a couple months, a co-worker and I decided that we could do things a fuckton better (no one else gave a shit at the new job either, big surprise) so we split off and are making our own company. I’m sitting in an airport in Charlotte, North Carolina waiting to get on a plane to Texas where we’ll be basing the new company. The business model for the new company will primarily involve sucking the massive aluminum and glass cock of Steve Jobs and occasionally taking it up the ass. This is a step up from fist-fucking PHP on a daily basis.

Why Texas? Because the beer is fucking cheap and there are lots of hookers there.

The new topics of this blog will cover:

  • How much Objective-C fucking sucks.
  • Steve Job’s dick.
  • Bitching about Node.js and custom V8 extensions.
  • Which entails fucking around with C++.
  • Some PHP shit on the side, of course, because it pays money.
  • And a tad of Python to keep everything lubricated.

Gonna try to keep it only QUALITY CONTENT, but you know me — I’ll probably get piss drunk one night and start ranting about how I tried to have sex with this one chick and she vom’d on me but it was okay until “she” turned out to be a transvestite which, in retrospect, shouldn’t have surprised me because her beard was more impressive than mine.

And I have an impressive beard.

10 comments