Sunday, August 3, 2014

A Bugs Life

Software bugs are everywhere. This shouldn't be so bad, except that software is everywhere — from your office computer, to your cell phone, home router, television set, car engine, and the list goes on and on. Heck, even an electric toothbrush has a tiny microcontroller programmed with firmware in it. Most of this software has been tested and tried, but bugs keep popping up nevertheless.
Last week I kept a bug diary. The dreadful results are described below.

Saturday, July 26 - FaceTime would not connect. After updating iOS the problem was resolved. Of course, “you must always update to the latest version”, but mind you, this problem never existed before. User experience: Everything was working fine, and then all of a sudden it didn't.

Sunday, July 27 - Tried the OS X Yosemite Beta. Okay, it's a beta release. Reported a bug where the GUI was actually messing up the screen. Sadly couldn't take a screenshot, because it would redraw the screen, effectively clearing things up. Luckily, the bug did reproduce every time.

Monday, July 28 - Didn't go near my computer, but today a colleague sent in a bug report for a piece of software of mine. My bad. One of those cases of “this should never happen”. A set of dictionary keys holds only unique items, so how could it be that an item appeared twice?

Tuesday, July 29 - Encountered trouble trying to build the PCRE regular expression library with gcc 4.9.1 on Linux. Somehow it wouldn't pass confidence tests. Reportedly did work with older gcc; smelled an awful lot like a compiler problem.
Found a recent online tirade by Linus Torvalds, in which he called gcc, I quote, “pure and utter *shit*.” Turns out the compiler's code generator emits buggy code.

Wednesday, July 30 - The pedestrian lights near the office stayed on “Walk” all day long. Nearly got run over by a BMW, as the driver hit the gas when he got the green light. Could have been caused by a loose wire somewhere, but I like to think it was a software bug.

Thursday, July 31 - Twitter app on iPhone kept crashing upon loading a particular news article. Who knows, maybe it was ad malware trying to infect the system.

Friday, August 1 - At last, a small victory. Fixed an endless loop problem in the RADIUS PAM module. Found some additional related issues, such as by the looks of it is a broken stupid unusual implementation of our RADIUS server.


Special bonus bug of the week (Linux): Exiting an interactive bash shell and getting “Illegal instruction” on the screen. This is most likely caused by stack corruption.

Sunday, July 6, 2014

Game On

I have a PS3 game controller lying around, so I got the idea to add support for it to an old SDL game code. This code was still using SDL 1.2, which is now a thing of the past. So the first thing to do was quickly porting it over to SDL 2, a more modern game programming API. It even includes a GameController API, and because of that, programming support for game controllers with SDL is remarkably easy.

Initialising initialisation
For initialisation, call SDL_Init() with extra flag SDL_INIT_GAMECONTROLLER. Additionally, you must open the game controller. The game controller is found by first querying the system for the number of connected joysticks.
    SDL_GameController *ctrl = NULL;

    SDL_Init(SDL_INIT_VIDEO|SDL_INIT_GAMECONTROLLER);

    int num = SDL_NumJoysticks();
    if (num <= 0) {
        printf("no joy connected\n");
        return false;
    }
    if (!SDL_IsGameController(0)) {
        printf("it's not a game controller\n");
        return false;
    }
    ctrl = SDL_GameControllerOpen(ctrl);
    if (ctrl == NULL) {
        printf("open failed: %s\n", SDL_GetError());
        return false;
    }
    name = SDL_GameControllerName(ctrl);
    printf("game controller: %s\n", name);
This code is just an example. It assumes the first connected joystick is indeed the game controller that the player wants to use. This is of course ridiculous, and you should really loop over all joysticks and open as many connected devices as possible.

Mapping the mappings
In them old days, supporting game controllers was ... problematic. The thing is, every game controller is different and there is no common standard among manufacturers for numbering buttons and analog sticks. Even a simple D-pad is different between different controllers — think XBox360, PS3, PS4, but even PS2, Logitech, OUYA game controller? SDL 2 solves this incompatibility by mapping the raw device button ids to generic SDL enums. You do need to provide the correct mappings, these can be imported from a flat-file game controller database.
    SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");

    if (SDL_GameControllerMapping(ctrl) == NULL) {
        printf("no mapping for %s\n", name);
        SDL_GameControllerClose(ctrl);
        ctrl = NULL;
        return false;
    }
Finally, enable events so that SDL will generate events for us to collect in the main event loop.
    SDL_GameControllerEventState(SDL_ENABLE);

Moving forward
When SDL game controller events are enabled, you will receive events of type SDL_CONTROLLERAXISMOTION in the event loop. You will find that SDL sends lots of these events, even when just holding the controller. This is just noise on the sensor, and the analog sticks are quite sensitive. Merely touching already registers movement. The ‘axis values’ are a signed 16-bit value, between -32768 and 32767. The SDL documentation says values between -3200 and 3200 are in the ‘dead zone’ where the sticks should be considered at rest.

The SDL_CONTROLLERAXISMOTION event boils down to this:
event.caxis.which     connected joystick number
event.caxis.axis      axis number
event.caxis.value     amount of movement

Click image to enlarge

Analog triggers L2 and R2 register as axis 4 and 5, but they only report value 32767 when pressed, acting like digital buttons. This could be a driver issue (I'm on a Mac) or SDL not properly supporting the triggers. I'm not sure.

Benjamin Buttons
SDL generates SDL_CONTROLLERBUTTONDOWN and SDL_CONTROLLERBUTTONUP events. Inspect event.cbutton.button to see which button was pressed.
The button codes are hard to find in the documentation, but look in SDL_gamecontroller.h to find the enums. The API is modeled after an XBox type controller, for PlayStation the button ‘A’ is a cross, button ‘Y’ is a triangle, etcetera. The ‘guide’ button is the PS logo button.
SDL_CONTROLLER_BUTTON_INVALID = -1
SDL_CONTROLLER_BUTTON_A
SDL_CONTROLLER_BUTTON_B
SDL_CONTROLLER_BUTTON_X
SDL_CONTROLLER_BUTTON_Y
SDL_CONTROLLER_BUTTON_BACK
SDL_CONTROLLER_BUTTON_GUIDE
SDL_CONTROLLER_BUTTON_START
SDL_CONTROLLER_BUTTON_LEFTSTICK
SDL_CONTROLLER_BUTTON_RIGHTSTICK
SDL_CONTROLLER_BUTTON_LEFTSHOULDER
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
SDL_CONTROLLER_BUTTON_DPAD_UP
SDL_CONTROLLER_BUTTON_DPAD_DOWN
SDL_CONTROLLER_BUTTON_DPAD_LEFT
SDL_CONTROLLER_BUTTON_DPAD_RIGHT

Any other business
I have a single player game so programmatically, I took the easy road and just map all buttons and stick movement to key presses, internally translating to a keyboard joystick. This works, but it's not good enough for multiplayer games. It also loses the ability to properly react to stick acceleration; you might want to scale the axis values to have a proper difference between large and small stick movement.

Some tutorials suggest you ignore the ‘dead zone’, but this is wrong because when you fully ignore those events, you are unable to detect when someone suddenly lets go of the joystick. Instead, the dead zone should be mapped to zero movement. You can also keep track of sticks entering/leaving the dead zone, and react correspondingly.

The DualShock 3 controller has pressure sensitive buttons. SDL has no support for measuring the amount of pressure. Nor does it support the sixaxis motion sensor. SDL 2 can do rumble however via its Haptic API.

The cool thing about SDL is that it also ports to other platforms, maybe most notably the Steam OS. Since I'm on OS X I also had a quick look at how to do this joystick & game controller thing in pure Cocoa — not so easy at all. I'm with SDL 2 on this one.

Links
SDL 2 GameControllerDB file
SDL 2 API by Category
How to connect a PS3 controller

Sunday, June 8, 2014

Go Rust Swift, Vala

In the WWDC keynote speech, Apple announced their new programming language named Swift. It looks like a scripting language, but it actually compiles to binary, giving you lots of performance. For years, I've been griping about the need for a programming language that's as easy as scripting, while delivering decently high performance. Lately, we've seen a number of new languages that do exactly this. So, it's time to discuss a few of these new, modern languages.

Go
Go was developed at Google and was first publicly released at the end of 2009. It's no secret that I'm a bit of a fan of Go, and I'll admit that of the four new languages discussed here, it's the only one I actually wrote a decent amount of code in.
Go is awesome for parallel programming. Goroutines and communication channels are plain brilliant. In fact, it completely changes the way you think about parallel programming. Go's duck typing system is marvelous, an enormous sigh of relief after decades of OOP and I just want to hug the creators of Go.
And yet, it has not yet become my primary language of choice. A big reason for that is mandatory CamelCasing. In Go, lower/upper CamelCasing actually controls whether the symbol is being exported or not; a really awkward design decision (golang's only mishap?).
Go is great for systems programming (ie. for UNIX tools, services), however ... it's as clunky as C when trying to parse a config file, and its flag command-line argument parser module isn't great either. Then I tried making a game in Go and simply couldn't get started because there were no stable bindings for the needed libs at hand at the time.
Go has a very “C feel” to it, every time I code in it I feel like I'm constructing a tiny, delicate machine. Everything about Go is excellently engineered. Some clever men with beards really thought things through.
What will golang's popularity be, five years from now? We shall see if it's truly to replace C/C++ as top systems programming language.

Rust
Mozilla's language named Rust started in 2006, but didn't go public until 2010. Rust is quite impressive, but the tutorial kind of lost me once it started on heap allocation, object ownership of memory, control of mutability, references, and confusing syntax involving glyphs. This leads to some pretty horrific code that shouldn't have been that way, in my opinion. Secretly, Rust is trying hard to be like C++.
The tutorial has some notes on features that are currently missing or buggy. In that respect, Rust is not ready for prime time yet. It does show a lot of potential and it did manage to create a buzz in the open source world, so check back once it hits version 1.0.

Swift
Apple's Swift language was announced only last week and is said to have been in development since 2010. At a glance, it's suspiciously a lot like Rust. This is particularly interesting given the fact that Rust is sponsored by rival company Samsung. What's the true story behind this?
Anyway, Swift looks awesome, and it's already miles ahead of Rust. Swift builds upon a foundation laid by Objective-C, all the way from NextStep to OS X and iOS. Cocoa and Cocoa Touch bindings are in place and ready to use. Under the hood Swift uses reference counting for garbage collection, and here lies a major pitfall; you should take care not to create any cyclic references, and/or know the difference between weak and unowned references. If you get this wrong, memory will leak just as it did in Obj-C. [Note that the same is true for Rust and Vala].
Swift lives in an Apple-only world, which should be no surprise — I suppose this compares to Microsoft's strategy regarding Visual Basic, C#, .NET.
There is no doubt that Swift is going to be huge on iOS, and probably also on OS X. Nobody likes Obj-C (apart from some weird guys like me). The matter of truth is, Obj-C is outdated, it has just been obsoleted by Swift. Two years from now, no one will be writing new applications in Obj-C.

Vala
Last but not least, there is Vala, which has been around since 2006 already. Vala is a Java/C#/Mono-like language for developing GNOME applications. It is said Elementary OS's main apps are built in Vala. The Vala compiler converts Vala code to plain C with GObject, which is in turn compiled by a generic C compiler. In a sense, Vala is just syntactical sugar, removing all the bad things that C has (the tedious task of programming intricate details), while keeping all the good (high performance).
Its syntax will be appealing to mostly Java and C# programmers. Personally, I get lost in the soup of keywords. A Vala source can be like a C++ code in disguise. There are just too many keywords; the designers forgot that less is more. It's probably too late now, but my wish for Vala is to be stripped down, simplified, made easier to work with.
Nevertheless it is a great choice for developing GNOME applications, and there is Elementary OS to prove it. Currently it looks like Vala's success is tied to that of GNOME, and it's a bit of a shame because it deserves more attention from a broader audience.
Vala wins the prize for “Best chosen name for new programming language” simply because googling it lands you on the right pages right away.

Links

Thursday, May 29, 2014

Programming is hard

I have always seen programming as something creative, like an art. And like in art, it is hard work to create something beautiful. It's hard to get the details right. If you get it right, then people will like the result, and of course, some may not because tastes differ and you can't make everybody happy. But aside from people's reaction to the picture painted, a painter also gets his satisfaction from mere crafting, using this technique here and that trick there, knowing the internals of his work.
Picture a musician, selecting an instrument to play, a rhythm, writing a melody.

That sure is a romantic view of programming. In reality, it's more of a purely technical process. When you want to accomplish goal G you are going to have to make work A and B together. This might be done with technique C. This is engineering. Apply a trick here, and it is called a hack. Hacks can be dirty hacks, or they can be clever hacks. In a security context, they might even be dangerous hacks.

Some say building applications is like building a house, and there should be blueprints for building software as well. Houses are built from small, simple building blocks. All houses have walls and a roof, a kitchen, a living and a bedroom, yet each house is unique. For each room, you can zoom in and work out the details. Users have the option of changing the wallpaper. And of course, a construction error may take down the entire house.
It's a nice metaphore that works well, but I suspect that whoever thought up that idea is not a programmer.

Programming is a mind game. The programmer builds a model in his mind, writes down the code and tries it. If it doesn't work, she tries to find out where it doesn't work. You may use a debugger or sketch it on paper but mostly the problem is cracked in your mind. Like a game of chess, it takes a lot of concentration trying to think six moves ahead, a single mistake will play out badly sooner or later.

Bugs are rarely ever “happy little accidents” like in Bob Ross paintings. They range from apparently random program crashes to worldwide Heartbleed scale disaster. Slowly the world is waking up, it has become apparent that eventually all software is flawed. Consequently, using the internet is as big a risk as a running across a highway, naked.

Programming is hugely underestimated. Programming is hard. It is really, really hard. The human mind was not made for this job. It is incredible that we have computers at all. Steve Jobs said that everyone should learn to program, because it teaches you to think. I agree a little, but it's like saying “Everyone can paint!” Or, “everyone should learn how to build a house.”

The best way to keep out bugs? Keep It Simple, Stupid. Simplify, simplify. Write code in a clear, consistent style. Add useful comments. Sometimes comment on why you did it this way. Test, test, test. Eat your own dog food.

There is a nice test to see if you've written good code. Open up a source file that you wrote six months ago. If you can't make out how it works within five minutes, then it's just not good enough. Now open up a source code that someone else wrote.

Boom. Oh, the horror.

Note that even this test is flawed, because you might not be seeing what you think you are seeing. Think about it. Programming is hard. And so is building houses.