Archive

Archive for the ‘Visual Studop’ Category

Debugger Friend or Foe

January 7, 2010 2 comments

Debugger Friend or Foe?

January 7th | 2009

Debugger: Friend or Foe

The debugger is something that most developers get familiarized with pretty quick. I am not really even going to bother explaining it as it’s such a ubiquitous tool. We all use it for one main reason though: something doesn’t work the way we expect.

I would suggest that it only be used as a last resort. The debugger, while effective and powerful, can lead you down rabbit holes—even if you are familiar with how debuggers work. Rather, start by writing a failing unit test that demonstrates the issue, and proceed from there. After all, if you are in the debugger it’s probably because something isn’t working right. And if something isn’t working right, shouldn’t you have a failing test?

Sometimes though, a failing test is just not enough. In these cases the debugger is a quick way to figure out how something works. It’s easier than sprinkling your code base with calls to Debug.WriteLine. The debugger also allows you to do cool things like modify where it is in the stack execution.

Let’s look at a piece of code. It’s pretty trivial:

class Program
{
    private static int _aNumber = 0;

    static void Main(string[] args)
    {
        int incrementedNumber = GetANumberIncremented();
        System.Console.WriteLine(incrementedNumber);
        System.Diagnostics.Debugger.Break();
    }

    static int GetANumberIncremented()
    {
        return ++_aNumber;
    }
}

Paste this into Visual Studio and hit F5 to make it go. The 3rd line of the Main method should cause you to break into the debugger. This is the same as setting a breakpoint. I only used it so I wouldn’t have to explain where to put a breakpoint. Using the mouse, hover over incrementedNumber. Hopefully you’ll get 1, like I did.

Now let’s try something interesting: Select GetANumberIncremented() including the parenthesis, but not the semicolon. Right-click on the selection and use a familiar tool, Quick Watch. Now we get 2. What gives?

It may be obvious to some, but not to others. The debugger is, in most cases, invasive. Quick Watch is handy, but as we did it on a method we forced the debugger to re-run the method GetANumberIncremented. It’s re-evaluating the stack. With the Quick Watch window open, click “re-evaluate.” Now we get 3. Again, and we get 4, and so on. It’s screamingly obvious in this example, but imagine if it was in a 3rd party assembly and GetANumberIncremented was a public method. We would have no idea what the method was doing. This is a pretty tame case as we’re only incrementing a number. But you can probably imagine instances where this could easily put an application into a state it wasn’t intended for.

Another thing you can get bitten by on the debugger? First chance exceptions. If you aren’t careful the debugger might tell you an exception is being thrown when it is actually being handled gracefully somewhere else. So when the time comes to run the application normally, it will work just fine.

Overall the debugger is an invasive tool that can lead you to some dead ends if you’re not careful.

I wouldn’t go so far as to say the debugger is evil. But I avoid it when I can and opt for unit tests instead. A unit test runs the code just as if it was being used by the application—or at least it should!

Kevin Jones is a Team Lead at Thycotic Software, an agile software services and product development company based in Washington DC. Secret Server is our flagship password management software product. On Twitter? Follow Kevin