The Debugging Troll

Rubber duck debugging is a well known technique in the programming world: when faced with a difficult bug or problem, there’s often great value in simply explaining verbally your understanding of the problem and the steps you’ve taken so far in your attempt to understand it. This is great if you’re talking to a person knowledgeable in the area you’re working in, but it can even work (in fact, might work better) with someone less well-versed in the code or system you’re working with than you are, since you’ll be forced to explain things that seem ‘obvious’. In fact, it can sometimes even work to just explain your issue to an inanimate object (e.g. a rubber duck). The simple process of explaining the whole problem in words sometimes makes the solution clear, or suggests new avenues for investigation.

But there’s another, more antagonistic imaginary friend that I sometimes keep by my side when debugging: the debugging troll. The debugging troll never believes me. I make assertions about how my code works that seem so obvious as to barely warrant asserting, and the debugging troll just says, “prove it”. He sits on my shoulder, watching everything I do as I’m debugging, and asking me whether I can prove that my assumptions about how the system works are correct. He whines at me to set unnecessary breakpoints, insert unnecessary debug print statements into my code, and use tools to verify things that I already know.

In short, he’s super fucking annoying.

But! I can’t count the number of difficult problems I’ve solved because of him.

So next time you’re stuck on an impossible bug, try summoning your own inner debugging troll. That branch is never taken because that condition never evaulates to true? Prove it. That method is only ever be called once on startup? Prove it. The version of that library that you have loaded is the one you intended? Prove it.

The thing about the debugging troll is that his track record for accuracy is pretty bad, but he only has to be right once in his doubt in order for your mental model of the system’s behavior to be blown apart and the truth to become clear.

660-543-7540

At work last week, I was validating a new code path against an old one by running them both over the same input, saving the generated MySQL queries for each one to a log file, and then running the saved query streams against a local MySQL installation and dumping the affected tables with mysqldump to diff them. (The run-dump-diff dance was necessary because the queries, while intended to be semantically identical, were in different forms.) Fun.

When doing this diffing, I noticed that many tables showed differences in the mysqldump output where the old path produced a value of -0, whereas the new path produced a value of 0. wat.

An experiment (with MySQL 5.5.20):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> CREATE TABLE zeroes (z1 DOUBLE, z2 INT);
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO zeroes VALUES (0, 0), (-0, -0), (0.0, 0.0), (-0.0, -0.0), ('0', '0'), ('-0', '-0'), ('0.0', '0.0'), ('-0.0', '-0.0');
Query OK, 8 rows affected (0.02 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM zeroes;
+------+------+
| z1   | z2   |
+------+------+
|    0 |    0 |
|    0 |    0 |
|    0 |    0 |
|    0 |    0 |
|    0 |    0 |
|   -0 |    0 |
|    0 |    0 |
|   -0 |    0 |
+------+------+
8 rows in set (0.00 sec)

You read that right: not only are both negative and positive zero values possible for DOUBLE columns (though not INT columns), but apparently a literal negative zero does not produce a negative zero column value unless it is quoted as if it were a string (there may be other ways to produce such a, value - I didn’t try too hard).

The negative/positive zero value distinction is not unique to MySQL - the IEEE 754 standard actually requires implementations to provide both positive and negative zero representations. In David Goldberg’s classic What Every Computer Scientist Should Know About Floating-Point Arithmetic, he explains some of the subtleties of signed zero behavior as laid out by IEEE 754:

If a distinction were made when comparing +0 and -0, simple tests like if (x = 0) would have very unpredictable behavior, depending on the sign of x. Thus the IEEE standard defines comparison so that +0 = -0, rather than -0 < +0. Although it would be possible always to ignore the sign of zero, the IEEE standard does not do so. When a multiplication or division involves a signed zero, the usual sign rules apply in computing the sign of the answer. Thus 3·(+0) = +0, and +0/-3 = -0.

It goes on, but I’ll spare you.

So positive and negative zeroes, sure - I can buy that. But the sytax for creating them in MySQL seems so strange as to be accidental.