ARC's Fast Autorelease

| No Comments

I just read:

http://rentzsch.tumblr.com/post/75082194868/arcs-fast-autorelease

Many people have noted how ARC is clever in the way that it avoids hitting the autorelease pool in some cases. It is clever, but in the articles I’ve read, they miss the point a little bit because they don’t mention why it is done that way.

A naïve approach would be to simply always put the autoreleased object in thread local storage and then check in your retain method. It would be much simpler (no assembly) and it would optimise manual reference counting code too.

So why bother doing it the way they do? A long time ago, I posed this question on the Objective-C mailing list and here’s the answer I eventually got: http://lists.apple.com/archives/objc-language/2012/Jul/msg00076.html.

Mounting NTFS Volumes Read/Write in Mountain Lion

| No Comments

If you want to use OS X’s native NTFS driver (i.e. Apple’s driver) to access NTFS volumes in read/write mode, you need to mount volumes with the “rw” and “nobrowse” options. You can either do that using the mount command, or if you want Disk Arbitration to mount things automatically for you, you can add an entry to /etc/fstab, like:

LABEL=xyz none ntfs rw,nobrowse

Change “xyz” to be the name of your volume.

Unfortunately, it’s not possible to have OS X automatically mount all NTFS volumes in read/write mode without a bit of hacking (e.g. by replacing /sbin/mount_ntfs with a script that massages the mount options before calling the original).

Note also that the “nobrowse” option (which you have to include) means that the volume won’t appear in Finder in the usual way.

To work around these issues, I suppose you could easily recompile a modified Kernel Extension and mount_ntfs; they are open source.

I don’t know how Apple’s native driver compares with other commercial or open source drivers that are available.

Code Signing Using New Apple Developer IDs

| No Comments

Mountain Lion comes with Gatekeeper and Apple will now provide you with a Developer ID to sign your applications.

If you need your application to work on older versions of OS X, you need to take care. By default, codesign will sign your application using a designated requirement that is built into the system. The default is controlled by the system that you are performing verification on, not the system that you’re signing on. The default on your current Lion system will be fine, but the default on Leopard (and possibly Snow Leopard) is not suitable and verification will fail. The problem is that if you use an Apple certificate it assumes that you’re writing actual Apple software (i.e. the requirements use “anchor apple”, rather than “anchor apple generic”).

To workaround this issue, you need to explicitly specify a designated requirement and have that passed into codesign. To pick a suitable designated requirement you can use the default. So sign your app just as you do now and then you can easily view the default by typing:

codesign -d -r- <path-to-app>

Now if you copy the “designated =>” bit and put it in a file (without the ‘#’ character at the beginning), you can now sign your app:

codesign -s -r <path-to-requirements> <other-codesign-flags> <path-to-app>

This will embed the requirements into your code signature and override any default that the system might try and use.

UPDATE: codesign in Mountain Lion has been changed so that it embeds explicit requirements so the above is no longer required. However, be aware of this issue in 10.8.0 regarding timestamps: http://lists.apple.com/archives/apple-cdsa/2012/Aug/msg00015.html.

Deadlocks

| No Comments

Mike Ash just posted in interesting article about deadlocks.

There’s another pattern that is related that I use. As he says, there is often a parent child relationship between locks. Now let’s say that you have chosen to always lock the parent first and then the child, I have found that it is often the case that I want to lock the child but then depending on some state, I then need to lock the parent. In that case, this is the pattern I use:

  BOOL haveParentLock = NO;

TRY_AGAIN:
  [childLock lock]

  if (someCondition) {
    haveParentLock = YES;
    if (![parentLock tryLock]) {
      [childLock unlock];
      [parentLock lock];
      goto TRY_AGAIN;
    }

    // Do something with both locks
  }

  // Do something that only requires the child lock

  [childLock unlock];
  if (haveParentLock)
    [parentLock unlock];

The important thing to note about this is if you have to release the child lock to gain the parent lock, it is important that you loop to check the condition again because you’ve released the child lock and some other thread might have sneaked in. (Some people might prefer to use a loop, but I tend to use a goto for this kind of thing.)

You also don’t want to be locking the parent every time because then you defeat the purpose of having child locks.

Prevent Spotlight From Indexing a Volume

| No Comments

To prevent Spotlight from indexing a volume, you can create a file called .metadata_never_index in the root of the volume.

Recovering Deleted Files

| No Comments

Recently, I had one particular file that I’d been working on that got corrupted somehow. Unfortunately, I’d let my Time Machine backup lapse somewhat and so I didn’t have a backup.

Anyway, the file wasn’t very big but it would have taken me a little while to write it again so I tried another way of getting the file back. I knew that Xcode uses atomic saves (it writes a new file and then uses a rename) so I figured, so long as I don’t write too much to the disk, there should be an old copy somewhere on the disk. Searching the entire disk would have been tedious though, so I wrote a quick program that creates a file on a volume that uses up all the free space. If you do this by conventional means, you’ll end up with a file full of zeros, but thankfully, OS X comes with the F_SETSIZE fcntl which allows you to set the size of a file without setting the contents. Here’s the code:

#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <err.h>

int main (int argc, char *argv[])
{
  int fd = open (argv[1], O_CREAT | O_RDWR, 0666);

  uint64_t size = 4096;

  for (;;) {
    if (fcntl (fd, F_SETSIZE, &size)) {
      if (errno == ENOSPC)
        break;
      else
        err (1, "fcntl failed\n");
    }
    size *= 2;
  }

  uint64_t high = size;
  uint64_t low = size / 2;

  while (high > low + 1) {
    size = low + (high - low) / 2;
    if (fcntl (fd, F_SETSIZE, &size)) {
      if (errno != ENOSPC)
        err (1, "fcntl failed");
      high = size;
    } else
      low = size;
  }

  printf ("done: %llu\n", size);

  return 0;
}

Obviously, you want to run this whilst booted from another volume and you have to run it as root.

So then it was a simple case of firing up HexFiend which I happen to know has pretty fast search and I managed to find my file.

Amazon's Silk Browser

| No Comments

From Amazon’s FAQ:

What about handling secure (https) connections?

We will establish a secure connection from the cloud to the site owner on your behalf for page requests of sites using SSL (e.g. https://siteaddress.com). 

Amazon Silk will facilitate a direct connection between your device and that site.  Any security provided by these particular sites to their users would still exist

This sounds a bit ambiguous. Are they or are they not acting as middle men? They might not be as it looks like they’re not using HTTP.

If this is true, I think there’s going to be a huge backlash against this. People simply won’t tolerate them being able to see your private traffic. What happens when a law enforcement agency asks for access? My money is on them changing this before they ship.

errno

| 1 Comment

errno is a macro on OS X and expands to this:

#define errno (*__error())

The reason for this is for thread safety. That means that in the debugger, if you want to see what the current value of errno is, you can type:

p *(int *)__error()

It’s important to remember that if you’re using errno, any system call can reset it. The following code is broken:

NSLog (@"errno: %d", errno);
if (errno == EIO)
  ...

The call to NSLog can, and probably will, reset errno. On 10.6 calls to the free library function (which NSLog can call) will usually reset errno to 2 (ENOENT), so bear this in mind if you’re seeing an errno value of 2 when you wouldn’t expect it.

As a consequence of this, you cannot single step through code in Xcode when you have “Use Data Formatters” checked, and expect errno to be preserved. You will find in many cases errno is reset to 2. In fact, I would recommend turning off “Use Data Formatters”—they cause many problems. Hopefully lldb will bring a non-invasive method of inspecting variables.

Was this post born from bitter experience? Yes it was.

Compile Time Checks

| 1 Comment

Here’s a handy macro you can use to do compile time checks:

#define CHECK__(line, x) typedef char check_##line##_[(x) ? 1 : -1];
#define CHECK_(line, x) CHECK__(line, x)
#define CHECK(x) CHECK_(__LINE__, (x))

You’ll get a compiler error if the check is false. Obviously the condition needs to be something the compiler can figure out at compile time. You might use it like this:

#pragma pack(push, 1)
struct x {
  uint8_t  a;
  uint32_t b;
};
#pragma pack(pop)

CHECK (sizeof (struct x) == 5)

I use it to check sizes of structures that have to match a protocol or format, for example, on disk structures that you know are supposed to be 512 bytes in size.

Static Analyser Invariants

| No Comments

If you’re not using the Static Analyser, you should be. However, sometimes you need to give it a helping hand in order to avoid false positives. Mostly you can use assert to tell the analyser that a certain path is impossible. The problem with that is that it will usually add code to your built product. You could avoid this by defining the NDEBUG macro in your release build but I don’t like to do that (and it isn’t by default); I prefer to leave assertions in my release build. Anyway, here’s some code you can use to do the same thing as assert but won’t add any extra code to your built product. You’d use this instead of assert when it might affect performance and is also obviously always true.

#if __clang__

static void inline static_analyser_no_return (void) 
  __attribute__ ((analyzer_noreturn));

static void inline static_analyser_no_return (void) {}

/* Use this to shut the analyser up without actually adding any code. */

#define static_analyser_invariant(cond) \
  do { if (!cond) static_analyser_no_return (); } while (0)

#else

#define static_analyser_invariant(cond) ((void)0)

#endif