A quick guide to debugging

Secret of the debugging wizards: Conditional debugging

To debug something as complicated as a virtual machine, you’ll want an easy way to enable and disable diagnostic output. I provide infrastructure in a module svmdebug.h, which enables each diagnostic output to be controlled by a key that you choose.

For example, my loader includes a call to svmdebug_value("instruction"). If the instruction key is set, my loader dumps the ASCII representation of every line passed to get_instruction. Keys are set on the command line using the Linux env command:

$ svm hello.vo
Hello, world!
$ env SVMDEBUG=instruction svm hello.vo
INSTRUCTION loadliteral 77 string 14 72 101 108 108 111 44 32 119 111 114 108 100 33 10
Hello, world!


If you have trouble encoding your VM instructions, you can call printasm to disassemble an instruction as soon as it is loaded:

// this example has not been tested
Instruction i = get_instruction(vm, vofile, &maxreg);
if (svmdebug_value("printasm")) { // ...expensive call...
    fprintf(stderr, "get_instruction returns ");
    printasm(stderr, vm, i);
    fprintf(stderr, "\n");

(If you’re aiming for peak performance, you probably don’t want to call svmdebug_value inside a loop.)

Conditional disassembly at an execution point you choose

Here’s another example: my vmrun function can skip the first dcount instructions, then start dumping the current instruction and the values of the registers it mentions:1

if (INSTRUMENTATION && --dcount <= 0)
    idump(stderr, vm, pc, instr, &RX, &RY, &RZ);

The dcount value is computed by passing svmdebug_value("dcount") to atol.

Function idump is like printasm, except in addition to disassembling the current instruction, it also dumps some machine state. If I set dcount to zero, my VM starts dumping right away:

$ env SVMDEBUG=dcount=0 svm hello.vo
[  0] r77 := "Hello, world! 
                                                              r77 = "Hello, world!
[  1] print r77
Hello, world!
[  2] halt

The more usual tactic is to use binary search to find a value of dcount that exposes exactly where the problem is.

  1. The INSTRUMENTATION is a C macro; if it is defined to 0 at compile time, then instrumentation is disabled and my VM pays no cost for diagnostics.