Over the last few weeks I’ve been grappling with a bug that just wouldn’t leave me alone. In the end, it took almost a week of pouring over TCP dumps and RFCs to figure out what was going on and, if I’m honest, the solution is a best-guess because I can’t figure out how to prove the theory.

It was a fun one, though, so I felt like writing it up :)

Read on →

A while ago, I found a pair of really useful GDB functions for debugging live Ruby processes on ThoughtBot’s blog:

ThoughtBot .gdbinit
define redirect_stdout
  call rb_eval_string("$_old_stdout, $stdout = $stdout, File.open('/tmp/ruby-debug.' + Process.pid.to_s, 'a'); $stdout.sync = true")

define ruby_eval

These proved really handy but they have a couple of problems relating to garbage collection and Macs, so I made a few modifications.

NOTE: If you don’t care about the explanation, scroll to the bottom of the post for the modified script.

Read on →

Many times I’ve been asked: “Why are you working on that? Is it for work?” referring to my tinkerings with kernel internals. “No, it’s not for work,” I reply, “I’m just interested in it.”

Other times this goes a bit further: “That looks horrible. Why would anyone want to work in C and assembler? No-one needs to understand that any more.” I’ll reply that I think it’s important to understand that which you rely on.

Then I’ll be told: “You don’t need to understand the internal combustion engine to drive a car.” They’re right, of course, but there is still value in understanding how an internal combustion engine works.

Then maybe someone will be telling me about the wonderful abstraction provided by the Node.js event loop, or the concurrency benefits of using a functional language. These things scare me, because I know that they eventually have to play ball with the real and terrifying world of the kernel and the processor, and only a fraction of a percentage of programmers have any interest in how either of those things run their code.

Read on →

Ever run into this one?

duplicate symbol _name in:
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [all] Error 1

It’s a bitch. Lemme explain what’s up.

Read on →

I’ve been wanting to start exploring the MRI Ruby source code for quite some time now, but didn’t quite know where to start. I wanted to devise a way of figuring out what parts of the Ruby source code were important, so if I were to run a “Hello, world!” program I could see exactly what the Ruby VM had to do to execute that.

Prerequisite Knowledge: It would help if you’ve used GDB before, but it should be self explanatory if you haven’t. If you’ve never used Ruby this post might give you tips on how to explore language code bases, but other than that it’ll probably be uninteresting. It’ll also help you if you have a vague idea of what a “symbol table” is in a binary file.

This is going to be quite meandering. I’m basically just going to be picking interesting things in the differences between certain running programs and looking at the C source to figure out what’s happening. If that sounds like your cup of tea, let’s do it! :)

Read on →

I’m really interested in the education of young people. A wise man once said to me if you’re in a privileged position and you have the capacity to help others get into the same position, it’s your duty to do so however you can.

With that in mind, a few months back I set out to help a friend get his university computing and innovation society some exposure to the programming industry (among other things!).

Read on →

Context switching is the method an operating system employs to implement “multitasking”. It’s the practice of having multiple contexts of execution in your system, often called “processes”, and switching between them really, really quickly to create the illusion that multiple things are happening at the same time.

It’s also a good method for efficiently dealing with processes that need to wait for an IO request, such as a hard disk read, to return. While one process is waiting, another can execute.

Prerequisite Knowledge: There will be some C and assembler in this post, so some familiarity with those languages would be good. Also, knowledge of what processor registers are will help.

You may also want to read this post at least twice. Just saying.

Read on →

In this post I want to walk through what a stack is in terms of the processor, what function calls are, why your stack can overflow or get too deep and how all of this relates to tail-call optimisation.

Prerequisite Knowledge: It would be useful if you’ve run into a stack overflow error previously. If you haven’t I want to offer a congratulations but it’ll happen at some point, I promise, and when it does it’ll be nice to understand what causes them.

Other than that, I’m hoping this post is accessible to anybody with reasonable knowledge of pointers and one programming language (C is ideal) under their belt, but useful for even the seasoned programmer.

Read on →

I’ve been on a quest over the last year or so to understand fully how a program ends up going from your brain into code, from code into an executable and from an executable into an executing program on your processor. I like the point I’ve got to in this pursuit, so I’m going to brain dump here :)

Prerequisite Knowledge: Some knowledge of assembler will help. Some knowledge of processors will also help. I wouldn’t call either of these necessary, though, I’ll try my best to explain what needs explaining. What you will need, though, is a toolchain. If you’re on Ubuntu, hopefully this article will help. If you’re on another system, Google for “[your os] build essentials”, e.g. “arch linux build essentials”.

Read on →

I started working on an x86-based pure-Ruby virtual machine! Not a virtual machine to run Ruby, a virtual machine built in Ruby that executes something that looks a little bit like x86 but isn’t. Why?

This is a write up of where I’m at so far.

Read on →