posted on Wednesday, March 01, 2006 12:58 PM
by
anoras
Heisenbugs and Conditional Breakpoints
Have you ever heard the term Heisenbug? If not, it is adopted from Heisenberg’s Uncertainty Principle in quantum physics. An Heisenbug is a bug that disappears or alters its behavior when one tries to observe it. In physics the principle states that on cannot assign the precise values of observable variables of a single particle even in theory. In software engineering a Heisenbug might be introduced by some force applied when debugging an application. Some Heisenbugs appear in the code, for instance within an if statement relying on System.Diagnostics.Debugger.IsAttached. With such a bug, the debugger will step into the infected code and you’re likely to spot the problem straight away. However, debuggers have more esoteric ways of introducing Heisenbugs that aren’t easily spotted. One particularly nasty Heisenbug I’ve seen a couple of times is introduced by conditional breakpoints. If you’re a C# developer and you forget that the equality operator in C# is “==” and not “=” you’re prone to Heisenbugs. Consider the following snippet:
31 IContext context=new Context();
32 context.Request request = new Request();
33 context.Request.Payload = ExtractMessageBody(soapServerMessage);
34 Uri actionUri = new Uri(soapServerMessage.Action);
35 string serviceName = actionUri.Segments[actionUri.Segments.Length - 1];
36 request.ServiceName = serviceName;
37 PipelineController.Execute(context);
Let’s imagine that the implementation of the PipelineController.Execute method is complex and uses a myriad of other classes to perform the desired operation. During testing you discover that when a certain service is requested the class does not behave as expected. To save yourself from endless F11 tapping, you set a conditional breakpoint at line 35 with the condition: serviceName=”BillingService”
When you try to figure out what is going on, all sorts of weird things start to happen. Requests for the “BillingService” receive messages used with the “OrderService” and the application seems to be horribly broken.
Unexplainable behavior like this is often an Heisenbug. In the scenario described above the conditional breakpoint assigns the value “BillingService” to then serviceName variable whenever the execution pointer passes, hence the value of request.ServiceName will always be “BillingService”. Since they’re not apparent in code, Heisenbugs like this are devious and though to spot, so be sure to pay as much attention to your break conditions as your “real” code, even during the most intense debugging sessions or else conditional breakpoints soon become a timewaster rather than a timesaver.