Geoffrey De Smet
Geoffrey De Smet

@GeoffreyDeSmet

16 Tweets 1 reads Nov 19, 2022
Most @java programmers only use 10% of their... debugger.
Use the full power of your debugger with advanced breakpoints.
Diagnose complex bugs in minutes, instead of hours.
Test your debugger skills with 4 challenges in this thread. Works with @intellijidea and other IDEs. 🧵
1) Challenge
Line 8 throws a division by zero exception.
Presume line 5 and 6 are hidden in 1000 lines of code.
How do we find out if variable a or variable b is causing it?
1) Solution: Normal Breakpoint
Put a normal breakpoint on line 8 to find out that variable b is 0 and therefore b is the culprit.
Ok, easy enough.
Let's make it a bit more interesting...
2) Challenge
Divide by zero at line 9.
Line 7 is hidden in 1000 lines of code.
How do I debug this efficiently at line 9?
2) Fake solution: Normal Breakpoint
A normal breakpoint at line 9 halts at every iteration.
Most values of i are fine, so it takes many "resume" click before the buggy state shows up. It's a PITA.
What I really want to know is: at which value of variable i does this blow up?
2) Solution: Exception Breakpoint
An Exception Breakpoint for ArithmeticException halts when the division by zero happens. It immediately shows the guilty value of i.
I can then mentally reason how those 1000 lines of code behave when variable i reaches value 666.
3) Challenge
In this case, there is no Exception, but still the code misbehaves.
How do I find out when line 13 is misbehaving?
What value is variable i?
Presume I can't alter the code to print i too, for example because this this code is part of an upstream dependency jar.
3) Solution: Conditional Breakpoint
A Conditional Breakpoint halts when the breakpoint is hit AND its boolean condition returns true.
In this case, it halts if the age is unrealistic (> 1000).
It shows this happens when variable i reaches 666.
Once you know that iteration 666 of the loop is problematic, you can put a Conditional Breakpoint at the beginning of the loop with the condition "i == 666", so you can step through the code inside the loop, one line at a time.
4) Challenge
A breakpoint in a "hot" method is painful: it could be called a thousand times (in earlier phases) before you want it to halt.
This code has 3 phases (= 3 calls).
Get a breakpoint on line 12 to halt in phase 3, during the last calcAge() call.
4) Solution: Disable Until Breakpoint
Put in 2 breakpoints:
- one on line 8 to flag when phase 3 starts, without halting (= not suspended)
- one on line 12 to halt, but disabled until the other breakpoint flags that phase 3 started
4) Alternative solutions:
- Pass Count Breakpoint, if you know how many times calcAge() is called before you want it to halt
- Conditional Breakpoint, if you can afford to rely in the variable count.
If these works: Great, use them!
But it depends on the case.
These 4 advanced debugging techniques don't just shine to find the cause of a bug.
They also help to understand what a piece of code behaves in particular circumstances.
Or - when you make code changes - how the behavior of a piece of code changes.
I hope you found these debugging tricks useful for your future bug hunts!
If you found this thread useful, you might find this one about JVM classloading useful too:
Or this one about profiling Java applications:

Loading suggestions...