your pc binary emulating visualizer

Blinkenlights is a command line debugger that focuses on visualizing how software changes memory. It's able to emulate statically linked i8086 and x86_64-pc-linux-gnu programs on the Linux, Mac, Windows, FreeBSD, NetBSD, and OpenBSD platforms.

Please join our mailing list! | web

Computers once had operator panels that provided an intimate overview of the machine's internal state at any given moment. The blinking lights would communicate the personality of each piece of software. Since our minds are great at spotting patterns, developers would intuitively understand based on which way the LEDs were flashing, if a program was sorting data, collating, caught in an infinite loop, etc. This is an aspect of the computing experience that modern machines haven't done a good job at recreating, until now.


What makes Blinkenlights unique is that its interface is designed under the assumption that terminal displays have grown larger than 80 columns. Therefore we can display many more panels of useful info than alternatives such as GDB. The most important panels are the ones that hexdump memory using Code Page 437. It's also able to automatically infer the type signatures of SSE registers based on the instructions. For example, here's an operating session screencast for a program that just prints images in the terminal.

please keep still and only watchen astaunished the blinkenlights — the jargon file

Watching this program execute (c / ctrl-c) at adjustable speed (ctrl-t / alt-t) it becomes clearer that the process of printing an image is basically a pipeline that goes: IDCT → Y′CbCr to RGB → decimate → sharpen → block render. Thanks to Blinkenlights we can also see that the RGB conversion is going slower than it should, because code isn't benefiting from SSE register vectorization. Many other common issues concerning micro-optimization, such as register spillage, become super apparent as well.

Software is conventionally written with an abstract theory of mind that's rooted in computer science concepts such as time complexity. However sometimes we get lazy at inappropriate moments and make our code accidentally quadratic. Modern CPUs have a feature called spectre that makes slow algorithms go as fast as good ones for small datasets, which unfortunately makes these issues difficult to spot. On the other hand, Blinkenlights behaves more like a conventional CPU so you concretely see the true impact of algorithms that are sloppy from a theoretical standpoint, thus saving you from the potential mistake of pushing that code into production to crunch data at scale.

Here are some of the features that are supported:

  • x86_64
  • i8086
  • x87
  • SSE
  • SSE3
  • SSSE3
  • ELF / COM Executables
  • VT100 + Xterm Mouse Mode
  • Windows10 Command Prompt
  • TTY / MDA / CGA graphics
  • Serial UART / Port E9

Blinkenlights is also a proper emulator in the sense that it can emulate itself. This can be accomplished by simply passing the binary as an argument to itself. Blinkenlights doesn't need any system commands to be installed beforehand (e.g. gdb backend) so this does in fact emulate the entire emulation process.

What are the tradeoffs? Blinkenlights is really good at creating a deterministic environment for program execution that can reproduce program state down to the finest detail across operating systems. It also runs as a first-class native binary on each system. But since it's an Actually Portable Executable it might not be able to perfectly conform to the conventions of your local operating system.

For example, you can use Blinkenlights on Windows, but you can't use it to emulate a PE WIN32 executable, since Blinkenlights doesn't implement Microsoft's APIs. You can however use it to run a Linux executable inside your Command Prompt or Powershell, as Blinkenlights takes care of the chore of translating Linux ABI to WIN32.

The Blinkenlights binary releases also work great on Linux, Mac, and BSD. On Linux specifically, they'll work on any distro since RHEL5 including Musl-based ones like Alpine. Some users might find it surprising that this portability comes at the cost of having no awareness of distro-specific conventions, like shared object search directories. You can fix that by passing -static and -no-pie to ld or gcc when linking programs you intend to emulate.

How you build your binaries also impacts how informative visualizations will be. The most important flag to pass is -fno-omit-frame-pointer so that backtraces will work. C++ name demangling works too if c++filt is on the path.

Lastly note that Blinkenlights is only a few months old, and as such, is still working hard to implement some intended ABIs. For example, clone() currently returns ENOSYS and the BIOS ABI surface area is currently limited to what's needed to bootload a program into long mode. Progress updates will be posted to the mailing list.

If all that sounds good, then please proceed to the download page. You can get started by reading the tutorial on the Real Mode page.