Terrible Terrible C

Today I want to talk about a couple of the terrible things that C (or a compiler extension) allows you to do.

First up: labels as values

gcc has an extension that allows you to treat a label as a value. Why it has such a feature is something of an enigma to me, but it does all the same. Most notable though is this snippet.

You may not use this mechanism to jump to code in a different function. If you do that, totally unpredictable things will happen. The best way to avoid this is to store the label address only in automatic variables and never pass it as an argument.

Of course, gcc does nothing to prevent you from returning the value of a label and then later jumping to it. In fact, that almost sounds like a challenge. And behold

#include <stdio.h>

void *label_value(int really)
{
    if (really)
        return &&LABEL;
    else {
        LABEL:
        printf("WHY!!!\n");
    }
}

void jump(void *LABEL)
{
    goto *LABEL;
}

int main()
{
    jump(label_value(1));
    return 0;
}
$ gcc lab.c
lab.c: In function ‘label_value’:
lab.c:7: warning: function returns address of local variable
$ ./a.out
WHY!!!

To be clear about what’s happening here. label_value returns the a pointer to the position in memory where goto will jump and continue executing. We’re passing this to another function, which is then jumping right back into the function that just returned. So when we call jump, the ‘jump’ function never actually returns, and label_value returns twice.

Aside from being completely awful, this works exactly as we expect. I can imagine all sorts of wonderful uses for this feature, including C’s long missing feature: continuations. Here’s a first order approximation.

#include <stdio.h>

void *label_value(int really)
{
    void *label = &&LABEL;
    int x = 2, y = 3;

    if (really)
        return &&LABEL;
    else {
        LABEL:
        printf("%d, %d\n", x, y);
        x = 2, y = 3;
        goto *label;
    }
}

void jump(void *LABEL)
{
    void *label[] = { &&WAT, &&WAT, &&WAT };
    int x = 4, y = 5;
    goto *LABEL;
    WAT:
    printf("%d, %d\n", x, y);
}

int main()
{
    jump(label_value(1));
    return 0;
}
$ ./a.out
4, 5
2, 3

Now we’re starting to have fun. Using stack locations as variables, we can control where each function jumps to as well as the values it sees for its variables.

Exhibit 2: Arrays as functions

C is a weakly typed language. C is so weakly typed, that you can cast an array to a function pointer and call it. This only works if the array lives in the right part of the object file though. Consider though:

#include <stdio.h>

unsigned char return_number[] __attribute__((section (".text"))) = 
      {0x55, 0x48, 0x89, 0xE5, 0xB8, 255, 255,0,0, 0x5D,0xC3 };

int main()
{
  int (*fn)(void);
  fn = (int(*)(void))&return_number;
  printf("%d\n", (*fn)());
  return 0;
}

We initialize a global array of chars and tell the compiler and linker to make sure it puts this array in the text section. The array itself contains a bunch of random seeming values.

In main we then declare fn as a pointer to a function returning int and taking no arguments and tell it to point to our array. Then we just dereference it and call it. What do we get?

$ gcc arraycode.c
/tmp/enggrid1.BU.EDU.tmp.Ymm30062/ccmP8SbE.s: Assembler messages:
/tmp/enggrid1.BU.EDU.tmp.Ymm30062/ccmP8SbE.s:3: Warning: ignoring changed section attributes for .text
$ ./a.out
65535

Why would we get that? Let’s consult objdump.

00000000004004ac <return_number>:
 4004ac: 55                     push %rbp
 4004ad: 48 89 e5               mov %rsp,%rbp
 4004b0: b8 ff ff 00 00         mov $0xffff,%eax
 4004b5: 5d                     pop %rbp
 4004b6: c3                     retq

This will just return the number 0xffff (65535) which is exactly what we observe.

One thing you may be tempted to do is to modify the array and change the return value of the function. Unfortunately this segfaults as the text section is not writable. There’s probably a flag in the elf file that would make it writable, but I’ve yet to find a way to flip it.

So what’s the point?

There is no real point to any of this. Nobody should ever write real code that does these things, but it’s fun to play with. I guess the real take away here is the C really is just portable assembly, and if you really want to you can pretty easily peel back the layers of abstraction that it gives you and write non-portable assembly with it!

Apple and the Platonic Calendar

Many words have been written recently about the realism in the design of Apple’s interfaces, and the benefit (or lack thereof) of skeuomorphisms. I would like to attempt a slightly different argument, and examine the philosophical ramifications of Apple’s design decisions. A word of caution though, I am neither an interface designer nor a philosopher, so the most I can hope for is to not butcher either. I will also offer the warning that this is meant to be an intellectual exercise, and not indicative of my feelings towards Apple, Platonism, or Calendars.

Platonism is the philosophy that suggests that for every “object” there is a pure abstract version of that object that exists somehow outside of this world. Consider an apple sitting on a table. The apple is just an instance of the abstract idea of an Apple. The same is true for the color of the apple. If it is red, this is just an instance of the idea of Redness. This idea should be easy to grasp for computer scientists, since we deal with Platonic Forms all the time in the guise of objects and classes. We even go so far as to create our own Forms!

But what does platonism have to do with Apple’s interface design? User experience is hardly a philosophical endeavor! Except that it is. Given the task of designing a calendar application, one has to consider what a calendar Is. This encompasses everything from the calendar’s appearance to its behavior to its limitations. In a very direct way, UX is the identification of the Form of what is being designed. A calendar application is an instance of a Calendar.

A defining quality of a Platonic Form is that it is ineffable. Our mere existence will never be able to truly perceive the object as it really is. As a result, there is a lot to learn from observing other’s attempts at defining these Forms. Examining the trade-offs and decisions made in the design of a calendar is enlightening as to what its designer thinks embodies the Form of the Calendar. In the case of Apple, it is almost trivial to define exactly what they think is the platonic calendar: a fancy executive-style desk calendar.

calendar

There are a couple of interesting consequences of this decision. The first being that it is relatively easy from a designer’s point of view to decide the appearance and behavior of your calendar; it should look and behave like the real object. Also interesting is how discrepancies between the virtual calendar and the True Object are rectified. In Apple’s implementation they discretely add features that the program should have to the context.

Perhaps the most interesting though, is thinking about what it means for an object in a computer to have its Platonic Form be an object in the real world. This would imply that for objects in a computer, like a calendar application, their zenith is their real-world equivalent. As history has shown, this is far from the case, as computer applications have surpassed their real world counterparts in nearly every way.

Let’s consider the calendar application further. Ignoring the uses of sharing calendars across networks, the virtual one still more useful than the physical object, if only for its ability to handle more information and dynamically adjust the events it is displaying. The only way that a physical calendar may be preferred is because it is tangible, and the virtual one is merely a representation.

But this is in a sense exactly the distinction between the Form of an object and the object itself. An instance of something is just a shadow of the object as it exists in the world of platonic ideals. In order for Apple to design a better calendar they have to make it tangible in some way. From this angle, the emergence of the iPhone and the iPad seem almost obvious. Obviously Apple didn’t conceive of the iPhone to make their calendar closer to a Calendar, but the logic still holds to a degree. In order to design a better user experience, Apple had to find a closer approximation of the platonic ideal and the route they picked was to create an experience that better mimics the ideal by being tangible.

At this point though, Apple is in a bind as they are sitting on a philosophical minefield. They must either must either continue attempting to improve their user experience by integrating more and more of the real world into their designs (culminating in the Apple Desk Calendar perhaps?), or they must reject their reliance on the real world as a the world of platonic forms and seek some higher representation of the calendar. Time will tell.

I mentioned before, but I’d like to reiterate: I most emphatically don’t buy my line of reasoning above. This was an intellectual exercise, not an attempt at depth.

Edit from 10/22/2013 – With the Release of OS X Mavericks and its abandonment of physical looking calendars, I have to say that my analysis here worked out far better than I would have anticipated.

Disabling CPU Frequency Scaling in Ubuntu

Recently I had to compile atlas in Ubuntu. Atlas does not like it when CPU frequency scaling is running because it screws up its timings. Ordinarily a simple change of the frequency governor (i.e. ‘cpufreq-set -g performance’) takes care of this and makes the processor run full-steam-ahead no matter what it’s doing, but Ubuntu seems to second-guess this and periodically resets the governor back to the ‘ondemand’ one. (In theory turning off powernap should stop this behavior, but for whatever reason it was’t behaving on the system I was using).

As far as I can tell, the file that’s in charge of this is ‘/etc/pm/power.d/cpu_frequency’, which uses the file ‘/var/run/powernap/cpu_governor.default’ to determine which governor it should reset to.

So, to permanently set the cpu frequency governor on Ubuntu (at least until a reboot), you can run ‘cat performance >/var/run/powernap/cpu_governor.default’ as root. This makes it reset the governor to performance periodically, which is enough to let atlas compile at least.

Unbricking a Western Digital Mybook Live

A couple months ago, my 2tb WD NAS decided to brick itself after I had to move it. Searching the internet, one can find that this is not exactly an uncommon problem, and is diagnosed by the unit showing a solid blue light (with the occasional flash to yellow). Mostly, none of the multitude of threads in the forums have any real solutions, or suggest to RMA the hard drive with Western Digital. This isn’t really a solution as far as data is concerned, so I decided to poke at it myself.

What You’ll Need

Unbricking the drive is a moderately involved process, and risks screwing it up even further. That said, if you want to try it here’s the things you’ll need.

Sata-USB adapters can be had for less than $20 on Amazon.

Setup

First the harddrive will have to be removed from its chassis. This is easier said than done, but can be achieved by prying up the plastic sides around the drive, while sliding the 2 pieces of it apart. It is probably possible to get it apart without breaking anything but breaking some of the tabs holding it together may be inevitable.

Once apart, the actual electronics are just wedged into the chassis on rubber-padded rails and can be pulled out fairly easily.

From this point, there are 4 screws securing the harddrive to the logic board. Once these are removed, the board and drive can be separated (note: one of the screws is under the rubber pad holding the LED light guide).

With the drive free, it can be hooked up to a comptuer via the Sata-USB adapter.

Fixing the Disk

You should now connect the drive to a computer, and have some sort of Linux distribution running (Ubuntu should work).

If you look at the disk with a tool like gparted, you’ll see that there are 4 partitions on it. These should be named something like sdb1-sdb4.

sdb1 and sdb2 are where the actual OS is installed. These are mirrored ext3 partitions, controlled by software RAID (this seems silly since there’s only once disk, but since there are also 2-disk versions of this NAS, and the same OS setup is probably used on both of them, it does make some degree of sense). sdb3 is swap, and sdb4 is where the data lives as an ext4 filesystem.

It’s possible to directly mount sdb1 and sdb2 (passing ‘-t ext3’ to ‘mount’ explicitly), but it should probably be avoided. Instead, tell the OS to treat them as a RAID array using ‘mdadm’. Something like

# mdadm --build /dev/md0 --raid-devices=2 --level=1 /dev/sdb1 /dev/sdb2

# mount /dev/md0 /mnt

should successfully get the partitions mounted if you want to poke around at them.

The actual reason behind the bricking seems to be the filesystem getting messed up from unpluggin the unit while it’s still running (there’s no power switch, so it’s hard to power off any other way). As a result, the actual problems with the drive can be fixed by just fscking them.

# umount /mnt

# fsck /dev/md0

will unmount, and repair the filesystem that the actual OS lives on. Odds are this will fix any issues caused by prematurely unpluggin the drive.

The data partition is a bit tricker. For some unknown reason, Western Digital decided to make this partition be completely incompatible with comptuers that are actually used. The blocksize on the filesystem is set to 16k, whereas 64-bit computers can only use a 4k block size. This means that it is impossible to mount this partition to get files off of it!

All is not lost though, as ‘fsck’ still works on the partition, despite the block size not being usable. As a result

# fsck /dev/sdb4

should fix this filesystem as well.

Once this is all finished, you should be able to plug the drive back in and have it work. I recommend not putting it back into the chassis until you have verified it is actually working.

Getting Data from the Data Partition

The block size issue described above makes it rather tricky to get data off of the drive in the event that the system paritions somehow got screwed up while the data partitions didn’t. It is not impossible though, and can be accomplished through the ‘debugfs’ command.

With the drive connected to the computer, run

# debugfs /dev/sdb4

This drops into a filesystem debugging interface. Run ‘help’ to see what all can be done from here. Most of the commands are really dangerous to run on a disk we’re hoping to salvage, so a great deal of caution should be taken. That said, there are a number that are quite useful. These include ‘ls’, ‘cd’, ‘cat’, and ‘dump’.

The first 3 do exactly what one would expect, with lots of extra filesystem data presented as well. ‘dump’ though, is the key to recovering data from the drive. ‘dump’ will take the contents of(read: a file) and dump it to a local file. This will only work on files (not directories), and can only dump one file at a time, but it can be used to recover important files if all else fails.