Debuggers: a modern 'Dr. Jekyll and Mr. Hyde'
I have to admit that I only use a debugger if someone wants to show me a problem he discovered within his debugger. Other than that I never used a debugger since I started to code in Java even thought I used debuggers before in C and C++. But when I started with Java there were no debuggers and so I have to rely on debugging statements and stack traces. When the first useful debuggers became available I had to switch between multiple OSs that, of course, one or more of them were not supported, yet. Finally, today, where many excellent debuggers are available but I really do not need them anymore and even think they do more harm than good. Dr. Jekyll or the debugger as useful tool can easily turn into a Mr. Hyde or a time sink if misused or overused.
Beside that for certain problems a debugger is a great tool it prevents many developers from focusing on the real problem that their code is plain buggy and that they have no clue where to look for. Stepping through a program only works well when the developer can remember where he came from and where he is heading to. But most of the time people lose that and when they found the problem they do not know how they got there in the first place and so the have to step through multiple times until they understand what caused the problem and how to fix it. A much better way is to look at your code, log output and, if you have, your test cases to localize your problem area and then focus on this area. For me this does mostly lead to a solution and I do not need a debugger anymore. With an AOP framework and a decompiler I can also debug third party library without a debugger.
You might think that I do not have to debug much and hardly have to deal with unknown code. As a J2EE application server developer I have to deal with many third party libraries, deployed application that are written in the company but also by customers and therefore I spend half of my time debugging code to find the problems and to fix it or to suggest a solution.
A debugger is like a telescope looking at the night sky and you have to find the North Star. With the naked eye you will find it pretty easily even when you have to remember that the rear leg of the Big Bear directs to it. The telescope needs to be directed pretty closely to the target otherwise you will miss it and waste a lot of time. Actually that would not be so bad but it prevents you also from learning the big picture of the night sky and to navigate easily through all the stars and nebulas. In addition a debugger can only work when program is not working as expected and therefore does not help in any way to prevent a bug. A debugger does not or barely work with race conditions (multi threading), class loading issues, network problems or any other runtime issues.
Here some tips how programs can be debugged without a debugger:
- Use a logging tool like ‘log4j’ to log the progress, warnings and exception stack traces
- Use ‘jUnit’ to write test cases and suites to make sure your code is working as expected and that the code does not regress due changes
- Narrow down the problem and check for previous warnings that may indicate the cause of the problem
- Use an AOP framework like ‘AspectJ’ or ‘AspectWerkz’ to introduce logging without changing the code
- Minimize side effects of other components or additional libraries
- Expect runtime problems from multi threading, class loading etc
For me this is good enough to master all bugs so far. But if you feel comfortable to use a debugger then do it even thought I would suggest that you try it first without and if all else fails fall back to the debugger. This will speed up the bug fixing process and make sure that you fix the cause and not mask the symptoms.
Happy Coding – Andy