Day 9: Learn To Use Your Debugger
Hi, this is the 9th part of a series of posts on 30 tips to becoming a better developer. If you would like to keep up to date with the topics that I am covering, just check the main post.
Debugging is one of the parts of the entire process of writing software that is time consuming and repetitive. While coding an algorithm can take a few minutes, debugging a problem found in an existing program can take anywhere from a few minutes to several hours of concerted effort.
However, despite the fact that we usually need to spend lots of time tracking down problems that show up in our code, it is interesting to see how few developers have familiarity with the facilities provided by their debuggers.
The most probable cause for this kind of overlook is that developers don’t see the activity of debugging in good sights, and with a reason. Spending too much time on debugging generally means that you didn’t spent enough time on the planning and design phases. It may also mean that you have been sloppy during writing and testing.
Still, there is no way to avoid the fact that humans make mistakes, and that these mistakes need to be fixed in some way. If we are talking about software, this means trying to find where the problem is happening and then finding a reasonable fix to the root cause of the problem.
Unless you are on the league of developers that don’t use anything else other than printf’s to debug code (I think Linus Torvalds is on this list), you need a debugger. So, you need to start looking at the debugger not as an evil that you should avoid, but as a tool that you can use on the right situations.
Other Uses for a Debugger
Once you get used to your debugger, you will start finding some uses for it that are not just related to finding and killing an existing bug. For example, a practice that many productive developers have is using the debugger as a first pass testing tool.
This method is not enough to replace serious testing, such as writing unit tests for all your code, but it is usually good enough to let you know if your “first draft” of code is working or not.
The idea is that, for each new method you write, you should put a breakpoint at the beginning of the method. Then, let the program run until the break point is reached. The next thing is to follow the execution of that part of the code step by step, until you are convinced that the results are correct.
Using the step-through method with each new method you write is a good practice, because it will give you more confidence on what you wrote. It is not a formal procedure like writing a unit test. But even if you are writing such tests it is still useful to use the step-through method. For example, while going through the code you could think of new tests that should be added to catch some extra cases that you didn’t consider initially.
A Debugger as a Poor Man’s Dynamic Language
The main reason why using a debugger can be very useful if you learn it well is that debuggers allow you to poke at the program as it is running, as opposed to just look at a listing of code. Even in a static language like C++, you still have a lot of freedom while using a debugger. You can, for example, change the contents of variables at will, and even modify the contents of specific memory areas.
The result is that the debugger can provide you with a dynamic view of how the code is working. For example, it is extremely easy to see the stack of callers that brought you to some point in the code. In an OO program, this can be a very useful information that is sometimes hard to find by just looking at the printed code.
Finding More Information
There is a huge amount of information about debuggers in their own documentation. You just need to take the time and learn what is available. Here are some links that will be helpful if you are using Visual Studio, gdb, or ddd.
You should also check Code Complete, which has a nice section on the marvels of debugging!
Go to the next post of the series: