Heisen Bug

A HeisenBug is a bug whose presence is affected by act of observing it.

For example, a bug which disappears in debug mode. It's normally dispersed by depressing dangerous digits in the direction of the dangling doughnut.

For more examples, see HeisenBugExamples.
Wow, that happened to me...
Back when I was hardware troubleshooting, a wise supervisor corrected my use of the phrase "intermittent problem". "There is no such thing!", he pronounced, "But some problems do have intermittent symptoms!"

This gives rise to the rather philosophical question: If no symptoms manifest, does a problem exist?

http://paul.merton.ox.ac.uk/computing/msbug.html
Once I had a bug which appeared only during step-by-step debugging. The Delphi debugger can display values of properties of objects. The values of properties can be computed by methods which can modify the object. So when I stepped through the code, the debugger displayed the value of the property and modified the observed object. Very confusing.

So you had a method to tell you what the properties of some object were, but that method actually modified the object? I'm confused as to how this can ever be a GoodThing and would appreciate being enlightened.

Yes. I am not sure whether this is always a BadThing, it was kind of LazyInitialization. However in this particular case it was really confusing obscure stuff deep in the Delphi's framework VCL. The problem was that in the Watch window I have had displayed some properties of some object. I was debugging through the code trying to find out, when the method Initialize is being called. So I placed a breakpoint into the method Initialize and debugged some other methods. When I jumped over one method, Initialize has been called right after the other method terminated; when I debugged the method step by step, Initialize has been called right after the first line. Actually, the Watch window updated itself every time the debugger interrupted the program. So, after every break, the Watch window read the property and the property read-method called Initialize. So not the normal flow of the program, but the debugger called the method Initialize. A very true HeisenBug indeed.
Here's one really nasty typo-turned-HeisenBug: "assert( x = 5 );"... -- AnAspirant

See AssertIdea
I tripped over one of these "debugger changed my code" bugs. VisualStudio.NET allows me to put conditions on a breakpoint, but no one bothered to check whether the code I entered was a boolean phrase. It's surprising hard to see the difference between "x == 5" and "x = 5", especially with some fonts.

Interestingly enough, you can put any code in the breakpoint condition. And I do mean "any". -- DeanChalker

To avoid this CompareConstantsFromTheLeft. And see also CodeComplete or WritingSolidCode.


I had a similar problem with MS DevStudio? (C++) a few years back. Calling a third-party DLL (DB driver) caused GPF problems that were unreproduceable in debug mode, regardless of whether I was stepping through or letting it run (which is why it didn't show up during regular dev testing, but was instead caught by the external testers). Turns out that the compiler optimizations were turned off by default in debug mode, and turned on in release mode, and it was the optimization module in DevStudio? that introduced the bug. Turning on optimizations in debug let me watch the call into the DLL tromp the stack below the calling point for the function, thereby trashing data that didn't belong to the DLL. Nice. Turning optimization off for the compilation of the file that called the DLL function in question removed the problem. (As it turned out, I discovered the same problem with a driver DLL for a different DB by another vendor, which reinforced the probability that the problem really was with MicroSoft's C++ optimizer.) -- EarlJenkins

I've had plenty of similar bugs that appear in release builds but not in debug builds. Without exception, the problem has always been a bug in my code. When you tell MSVC to compile in debug mode, it puts padding on the stack so that it can detect when your code trashes the stack. It will put an epilogue on each function that checks the contents of the stack padding to make sure it wasn't overwritten. That mechanism generally works, but not always. If you happen to trash the stack in a way that leaves the padding intact, then it will go undetected in debug builds, but in release builds, it will actually trash the stack. Other times, the epilogue doesn't get executed for whatever reason, so the padding just swallows the stack trash and gives you a false sense of security. -- MichaelSparks


It is our destiny to create more and more hard-to-analyze HeisenBugs by the creation of less intrusive debuggers. Maybe it is possible to create a system theoretic approach that actually makes the bugs show themselves rather than to hide.
This happens in event-driven debugging sessions. You can't effectively simulate LostFocus?, for example, when the debugger itself forces focus changes.

For the few occasions when I've debugged a problem like that (and knew that was the area to suspect), I've had luck using "remote debugging". That way the debugger's UI can't interfere with the debuggee's UI.
See also: BugTheory, BohrBug, MandelBug, SchroedinBug, HeisenbergUncertaintyPrinciple, ProgrammerProximityDetector
CategoryBug

EditText of this page (last edited June 5, 2008)
FindPage by searching (or browse LikePages or take a VisualTour)