Tuesday, October 19, 2010

Iterative Debugging

Sometimes when faced with a bug, I find it difficult to not plow right through, trying to figure out what logic is wrong. This fine, but needlessly slow compared to following some basic debugging patterns.

Let the logic tell you what logic is wrong. So many solutions to debugging come from binary searches. For example, binarily replacing changed code until you pinpoint what's wrong, binary searching revisions until you find when the bug was introduced, binarily (and recursively) blocking off chunks of code with a profiler to find the origin of a bottleneck.

What caused me to remember this (for the umpteenth time) now, was that I was able to use Ocaam's Razor on two seemingly identical pieces of code:

This works (copy-pasta from an example):
oQ.X() = (float) (lT0*iQ0.GetX() + lT1*iQ1.GetX());
oQ.Y() = (float) (lT0*iQ0.GetY() + lT1*iQ1.GetY());
oQ.Z() = (float) (lT0*iQ0.GetZ() + lT1*iQ1.GetZ());
oQ.S() = (float) (lT0*iQ0.GetS() + lT1*iQ1.GetS());

This doesn't:
oQ = lT0*iQ0 + lT1*iQ1;

By pairing down the problem set, half of the function by half of the function, I was able to determine in log2(n) steps (where n is a factor of lines of code) where my exact problem is. Now I know that either

  • my scalar multiplication of Quaternions is broken or
  • one of my constructors is broken
After double-checking my constructors and multiplication operators, it was a faulty Normalization function that was occurring each time a Quaternion was constructed. If I had just stared at it, I might have made the assumption that it was fine simply because it mathematically made sense.


Let logic logic for you.

No comments:

Post a Comment