A Story of a Heisenberg Hunt

It is past 4 am, and the bug hunt is over. It was a weird one. One that I’ll remember. It led me on a wild exhausting chase through dark nooks and crannies of a horribly-written nightmare of a code base. What made it weird was that, with the same random number seed, I got different behavior depending on whether there were some (debugging-related) print statements in some parts of code.
Even if these statements were in parts of the code that were entirely separate from where the failure was happening. Even — and this was most perplexing to me — if the statements were entirely innocuous in that they were not accessing any variables, e.g.:

fprintf(stderr, "\n");

I was, in fact, dealing with what Wikipedia calls a “Heisenbug“:
a “bug that disappears or alters its characteristics when an attempt is made to study it” (Wikipedia).

A couple of hours of slicing, dicing, commenting, uncommenting, rewriting, and re-rewriting code (thank the heavens for version control) trying to pin down the problem was getting nowhere: I just could not get consistent behavior (how could printing a newline to the standard error at the beginning of the program make a difference as to whether it failed in iteration 5 or iteration 5000????!).

The answer lay in a floating point comparison: two floating point variables were being tested for equality with no allowance for floating-point error in one branch of the code. In some runs, they tested equal, and in others they did not, even though they effectively were.

That is, if you want to explore the exciting nexus of quantum mechanics and programming and (maybe) completely ruin your night, then do this:

if (a == b) {
...

This, my friends, is one additional potential cause for a Heisenbug: floating point error.

On the other hand, if you are quite happy with programming under good old Newtonian mechanics and like your deterministic automata to remain deterministic, preferring to explore the wonders of the quantum universe after the dissertation deadline, then isolate the uncertainty to remove its sting:

if (fabs(a-b) < 0.000001) {
...

Leave a Reply

Your email address will not be published. Required fields are marked *