liveBook · Manning

Heisenbug

As explained in Troubleshooting Java, Second Edition

A Heisenbug is a software behavior or failure that changes when the program is observed or interfered with, especially through debugging.

A Heisenbug is a failure or behavior that changes when observation or interference changes the program. Multithreaded applications are especially vulnerable: pausing execution with a debugger can alter the timing and prevent the original problem from appearing. section 1.2.1 section 2.3

Treat the debugger as one investigative instrument, not as a neutral window into every failure. If stepping changes the symptom, compare observations made with logging, profiling, mocks, or stubs; reducing execution to one thread can sometimes make debugging practical. section 1.2.1 section 2.3

Ask these diagnostic questions:

  • Does the failure occur only without the debugger, or only after stepping and pausing? section 1.2.1
  • Could timing explain the change, such as an expiring access token, timer, or short-lived external session? section 2.3
  • Would logs or a controlled stub preserve observations without changing execution as much? section 2.3 section 1.2.1

Multithreaded failure

A multithreaded application behaves incorrectly during normal execution, but appears correct when paused in a debugger. The pauses have changed thread timing, so the observed run no longer represents the original failure. Capture behavior with logging, consider profiling cautiously, or simplify the investigation by reducing active threads to one. section 1.2.1

Figure 1.6 A Heisenberg execution. In a multithreaded app, when a debugger interferes with the app’s execution, it might change how the app behaves. This change doesn’t allow you to correctly investigate the initial app behavior that you wanted to research.

Illustrates how debugger interference can change multithreaded execution and block investigation of the original behavior. section 1.2.1

How Troubleshooting Java, Second Edition covers it

How deep it goes
Defines debugger interference and gives alternative techniques, but does not descend into thread-dump or heap-dump analysis.
Examples
Uses multithreaded execution, expiring access tokens, timers, and short-lived external sessions as timing-sensitive cases.
What you can do after
Diagnose with logging, cautious profiling, controlled stubs, or reduced thread counts when debugging changes the symptom.
How it connects
Connects debugging with multithreading, logging, profiling, mocking, stubbing, and thread dumps.

Also explained in

Compare how 2 books explain heisenbug →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Troubleshooting Java, Second Edition. The section links point to the parts of the book it draws on.