Design Article

How to use a debugger as a bug preventive tool

Nathan Field

12/28/2009 10:50 PM EST

Generally speaking, a debugger is thought of as a tool to use after a problem is encountered, when its cause is not obvious. Although a good debugger is the best tool for diagnosing problems and defects in software products, their use in the code writing phase is often overlooked.

In this article, I will discuss how and why you would want to use a debugger before you know that you have a bug to track down and fix. At the end of the article, I will discuss some of the basic requirements that a debugger must meet in order to apply this technique.

Keep in mind that this approach is not intended to replace existing practices that also attempt to reduce bug rates. Testing and design are still important components of good software development. First though, some facts to frame the discussion:

1) The longer a bug is in a product, the harder and more expensive it is to fix. For example, if a developer discovers a bug in the code they have just written, it may take only moments to fix. If the bug is discovered later, the buggy behavior may actually be depended on other components that were written later. Fixing it may require major restructuring. Worse yet, if the bug is discovered after the product has shipped, it may require recalling the entire product. The sooner a bug is fixed the better.

2) Studies have shown that there can be as many as 1 bug for every 8 lines of code. Over time, testing will discover some of these, but others could languish in the code for a long time before they are discovered by an important user hitting an edge condition that wasn't fully tested.

3) Other studies have shown that 50% to 75% of the time spent on a typical software project is spent on testing and debugging. Additionally, the large amount of time spent makes it very hard to schedule projects.

4) Many software development methodologies attempt to address these issues by reducing the number of bugs that get built into the product in the first place.

We know that all code has bugs in it. The sooner you can eliminate these bugs, the fewer problems will need to be fixed in the testing and debugging phase and the sooner your project can be released.

So how does a debugger help you do this? Consider the following:

1) You know the most about your code immediately after you write it.

2) In any reasonably sized product, you can't really know how your code will interact with pre-existing code until you run it

3) In some cases your code will appear to work, when actually it is failing in a subtle way that you may not discover until later

Given these three points, we can conclude that the most opportune time to detect and repair bugs is immediately after you write the code. A good debugger can serve as a code inspection tool to help find the new bugs that have inevitably been added.


Next:




sriramv.iyer

12/17/2009 3:47 AM EST

I agree it us a new perspective. It is not always feasible esp if the code is huge.

However, Unit Testing is a repeatable process, and test coverage should be decent. We can't keep doing this everytime code changes.

Sign in to Reply



piyush_

12/17/2009 10:17 AM EST

This is a good practice, developers do this from time to time when they don't yet have a feel/confidence of whether the newly created software is actually doing what it is supposed to do and is to make sure it is not somehow magically producing the limited test run result and as the author correctly points out, this is best done earlier than later. A good programmer will not attempt to run the code until he is mostly confident that it will run successfully but when he does run the code after such level of comfort, he will be the most skeptical. It is difficult to switch between these opposing roles and in the latter part, using the techniques mentioned in the article comes handy. It is more suitable in a bottom-up development style i.e first on little pieces of software so you know the building blocks are solid before you put them together to build higher levels of software, but as correctly pointed, is not a substitute for repeatable unit testing (which can come after this step because comprehensive unit tests also take a good amount of time). Good tools also have code coverage (so you know if your unit test didn't cover some code), run-time uninitialized memory read detection, run-time out of bounds access detection etc (there are also static analysis tools that detect statically detectable problems before even you run the code). Asserts and tracing variables/signals in the code also help to see if assumptions and intermediate quantities are valid. No one tool is a winner over others, all tools are available to the developer to use when it makes sense during software creation and repair to be productive and effective, the more variety the better (even if some features are used very rarely, because they are useful when they do need to be used). Tools need to keep evolving to meet needs such as multi-core debug, advanced tracing and visualization etc and future tools may also have touch screen UI enhancements for more intuitive debug.

Sign in to Reply



Lundin

12/18/2009 9:40 AM EST

Huh... doesn't everyone do this? Are you saying there are programmers who are just writing all their code in a flurry of keystrokes and then press run and hope it works? I don't think I've ever seen anyone do that. Fresh rookies still in school maybe, but none who has gone through a comp. sci degree, let alone hardened veteran programmers with years of experience.

Sign in to Reply



CapnKernel

12/21/2009 9:33 AM EST

Nathan, a big fat AMEN! to everything you have written here. I use this technique to give me confidence that what I wrote is really what I meant.

Lundin, you better believe the *majority* of programmers just hit the button, and if the final number is good, ship it. For these people, their testing is never more than a form of black box testing. Drives me crazy!

Using a debugger helps me get into the mind of the program (if that makes sense). As I go past a particular point in the code, I have everything I need to be able to audit that code's interaction with the rest of the system.

I put a breakpoint on every major calculation, and every branch point. For new code, that may mean hundreds of breakpoints. As Nathan writes, I then run the code every which way, clearing breakpoints if the code passes my beady-eyed review, until there aren't any breakpoints left. It's like an interactive coverage tool.

piyush_ likes unit tests. I like to do unit tests too, but the payoff for unit tests comes later, whereas the payoff for using a debugger to do your "live desk check" pays off immediately. Both are complementary and valuable.

One major requirement that Nathan omitted is that your platform can support having enough breakpoints to cover the code to the density you need. It continually drives me crazy that the Atmel CPUs I use only support 3 breakpoints.

A minor requirement is to have a stable platform! It's very frustrating if your debugger crashes, or there's a problem with debugging support on your platform, and you lose the 180 breakpoints you haven't cleared yet. Without stability, the value of this technique is greatly diminished.

In general, a fine article. Why don't they teach techniques like this at University?

Sign in to Reply



noldsworth

12/21/2009 4:36 PM EST

how is this related to opensource software ? Is Multi Debugger opensource ? It shouldn't have opensource in the url.

Sign in to Reply



KarthickG

12/22/2009 3:48 AM EST

During a typical SW build-test-release process, I do put quite a few printfs to see the program flow and inspect state variables. It is not a single print towards the end that determines a pass-fail criteria. In other words, unit tests are not black-box, they do also inspect the internal states and check if they are as expected.

I would rather prefer using printf, than stepping in a debugger - gives the same information and easier to automate.

Sign in to Reply



MarkVZ

1/7/2010 1:23 PM EST

Caution to KarthickG: be very careful using printf in a real-time system. It will mess up the normal timing. It may hide or create race conditions.

Sign in to Reply



mike32768

1/8/2010 1:42 PM EST

It is scary to think that programmers wouldn't use a debugger regularly. However, I am sure they do just that - I have seen posts in several online "help" forums in which it is apparent the people needing help have NEVER used a debugger.

All the "quality control" or "process improvement" or "code/peer review" in the world won't replace the original authors doing their own debugging.

Sign in to Reply



Please sign in to post comment

Navigate to related information

Datasheets.com Parts Search

185 million searchable parts
(please enter a part number or hit search to begin)

Feedback Form