If it’s not already, this blogpost will give you some practical tips on how to make your debugger your best friend. If you are new on the job and thrown into a big legacy system, it can sometimes be really difficult to understand the flow of the code. Even when you are familiar with the codebase a particularly complicated piece of code may leave you stumped. A debugger can be a helpful tool to understand what is happening and where information stems from. Going back to the basics and really getting to know how the debugger(s) in your IDE(s) work can be a real boost.
This blog post is not supposed to be a tutorial for any one IDE. Instead I will go through debugging concepts that are present in most IDE, as well as some nifty tricks found in specific debugging tools. I am most familiar with the Eclipse debugging tool, so most of my references will point to there. However, the concepts that I cover are present in most debugging tools.
Get to know your break points
Debugging is stepping through your code, line for line, while being able to monitor the changes in variables in your code. Most of the time you are not interested in each and every line of code. You are interested in a specific part of the code or a specific variable. As such, you want to be able to tell your debugger when it should pause execution for closer inspection. You do this with breakpoints.
The most basic breakpoint will simply stop the execution at the given line; however, you can do much more with breakpoints! One of my mostly used breakpoints is the conditional breakpoint. As the name suggests it will halt execution when a given condition is met or when a value changes. This allows you to focus on what is really important.
A really helpful break point is the exception breakpoint. If you have no idea why an exception is thrown and you want to find out the cause, exception breakpoints will halt execution right when the exception is triggered. It is then easy to see what triggers the exception, and what the cause of that trigger is.
If you are working with a multi-threaded application and you want to follow the execution of a specific thread, you may want to filter a breakpoint on a specific thread. Then you can follow the execution of that thread without having to worry about being confused by another thread.
You can also do some additional things with breakpoints, such as suspending execution when the breakpoint has been hit a certain number of times or suspend all breakpoints until a certain breakpoint has been reached.
Get to know the controls
When you have reached the code of interest for debugging, you may want to follow the execution more closely. To do this you have some progression controls at your disposal.
The basic progression controls for debugging are fairly self-explanatory. The step into option will go into the statement you are currently at. The step over option in contrast, will jump over the statement and show you the result after. This means that if you choose to step over a big method, you do not have to follow it through the entire method, you will only see the result.
The final basic progression tool is the step return, which will take you out to the caller of the current statement. If you are in a method this would mean that you would go to the place where the method was called.
A lesser known, but very useful progression option is the drop to frame option. Using this will take you back to the beginning of the current frame you are in. In the case of a method, this would mean you will be taken back to the very top of the method. This can be very useful while finding out where an issue originates from. You might step over a piece of code with the step over function and find that a method call is the root of your error. Unfortunately, step back is generally not an option while debugging. Drop to frame will take you back to the beginning of the code piece you are currently in though, and you can choose to go into the statement that caused the error again.
The drop to frame option is also very useful if your IDE and debugger allows for hot changes. That is, they allow you to change the code while debugging without having to recompile and rerun your application. If you are working on a big project that takes a long time to compile or run this can be a great time-saver. In Eclipse while working with Java, you can do code changes that do not affect method headers and similar big changes. After doing a change and saving you will automatically be brought to the top of frame, allowing very quick feedback for your change.
If you are working with applications that might be triggered by another application, you may think that you cannot debug your application properly. These kinds of situations can be really difficult, as it is not the application that you want to debug that drives the execution. However, if you are developing in Visual Studio you are in luck! Visual Studio allows you to attach a process to your debug session. This will in turn trigger the execution in the application you are debugging. To do this go to Debug > Attach to process and select the process to which you want the debugger to attach.
While debugging may seem basic, and the prospect of debugging your own or others code may be daunting, I have found that it really helps me understand the applications that I am developing. While I was still a student, I rarely saw the use of the debugger, it was mostly just a bothersome tool that never wanted to work for me.
When I started working in a bigger project with more complicated data structures I realized how useful it can be. Getting familiar with the tools and options available to me showed me how essential good debugging skills are to my work as a developer. It takes some getting used to, but as the saying goes, practice makes perfect, and these days the debugger is my most beloved development tool. I hope this blogpost has given you some food for thought and might have introduced some concepts that you were not aware of before.
Best regards ,