The Visual Studio Debugger: A new series on an old topic


The Visual Studio Debugger has long been regarded to be one of the industries best debugger. The VS debugger’s ability to give developer’s insight into the running behavior and state of their .NET and native applications has been the foundation of what has made Visual Studio the IDE of choice for millions of developers around the world. Over the years, Visual Studio has seen many many features come and go into the product line, but the basic functionality of the debugger has been a constant. The ability to easily set breakpoints, step, view variables, and run have been at the heart of every developer’s workflow on the Microsoft platforms.

The debugger is a very interesting feature set in Visual Studio. It is one of those areas of the application where you can walk up to any VS developer and ask “Hey, do you know how to use the debugger?” They will undoubtedly look at you funny and say something like “Of course. What, is this a trick question?”

But how many developers actually know how to make the debugger do their bidding? How many know how to only use the debugger as a last resort, and when you do have to use it, maximize your time with it in order to get back to what you need to be doing, which is maximizing value for your end users? Turns out, the Visual Studio debugger gives you much more capability than simply the ability to set a breakpoint. The VS debugger has so many little features designed to make your life just a touch easier in many and different ways, most developers either haven’t discovered them, or they haven’t realized how those features can be applied in a way that maximizes their effectiveness.

There are many reasons for this, ranging from real discoverability issues with the features, to the lack of desire of the developer to reach for anything beyond the bare minimum feature sets. Regardless, I’d like to take the next few blog posts and examine some of these features. Features ranging from IntelliTrace, a marquee feature of the Visual Studio 2010 Ultimate product, to Trace Points.

There have been many articles, books, and blog posts written about the debugger, but it has been awhile since the topic has seen some fresh print. But as I said, since many of the features in the debugger have remained constant, much of the content out there is still quite relevant. I highly recommend checking out Jim Griesmer’s posts on the debugger, and of course, John Robbin’s debugging books are a must read. For the more advanced, I would highly recommend Mario Hewardt’s books ( this one and this one ). And of course, the MSDN documentation isn’t a bad place to start either, but for some reason most folks seem to forget or assume that the debugger isn’t documented! Go figure.

I don’t know how many posts will make up this series, but I do know that my intent is to provide you with more pragmatic information that you can use in your everyday. If I can help you save 10 minutes a day just by showing you some trick with the debugger, I’ve done my job!

Though I have a pretty good idea of the topics I’d like to cover, if you have a topic related to debugging inside Visual Studio that you are very interested in, please give me a shout either via the comments on this post, or via direct email.

Cheers,

Cameron

Comments (7)

  1. Great idea for a blog post series!  Developers easily miss out on an awesome set of tools that can shave tons of time savings during the week.

    Looking forward to reading more…

  2. Wendy says:

    well,I love 'debugger',but also there are some uncomfertable use of it.like why there is no data debug point in .Net,but it is use so perfect in VC

  3. camerons says:

    @Wendy I don't understand what you mean. Can you tell me more?

  4. Anish Patel says:

    Great idea on a blog post series. Will you be covering data visualizers at all in the series?

  5. camerons says:

    @Anish Yes, definitely plan on talking about visualizers. Anything in particular you are looking for more information on in that regard?

  6. Dan Moyer says:

    Good topic.  Will look at your references and looking forward to future postings here.

    Recently read jaredpar's WebLog, "DebuggerDisplay" attribute best practices.   I really liked Preferred Pattern at the end his blog.    His tip, not only helps in seeing data within a collection, but used well too for doing a Debug.WriteLine to direct output to a debugger window, like SysInternals DebugView– to capture / watch collection data interactively.  

    His tip recently helped me debug more effectively a recursive call for generating a visual tree, and viewing the output in DebugViewer was more useful than hitting a breakpoint on each iteraction and inspecting the values in the debugger, yet provide the same data if I do stop on a breakpoint to view the data.

  7. Les Lewicki says:

    tip – maybe is trivial for some of you, but…

    seeing what's in debugging msxml dom objects in native c++

    create c function (I did simple.cpp) and build it into .obj – keep this somewhere – it's done once

    then link the .obj as library to you (any) dll and that's it..

    now when you want to see what you have in you xml object at the breakpoint

    open Immediate Window (Ctrl+Alt+I) and type

    ?ViewNode(lqiNode.m_pInterface, "xml");

    key is to use .m_pInterface for those object…

    code for simple c method – remember needs to be pure c (and pure pointers) I'm using …

    void ViewNode(MSXML2::IXMLDOMNode* pqiNode, char* ppszWhat);

    void ViewNode(MSXML2::IXMLDOMNode* pqiNode, char* ppszWhat)

    {

    if (pqiNode)
    
    {
    
        BSTR bstr = NULL;
    
        try
    
        {
    
            if (_stricmp(ppszWhat, "xml") == 0)
    
            {
    
                pqiNode->get_xml(&bstr);
    
            }
    
            else if (_stricmp(ppszWhat, "text") == 0)
    
            {
    
                pqiNode->get_text(&bstr);
    
            }
    
            else if (_stricmp(ppszWhat, "name") == 0)
    
            {
    
                pqiNode->get_nodeName(&bstr);
    
            }
    
            else if (_stricmp(ppszWhat, "type") == 0)
    
            {
    
                MSXML2::DOMNodeType nodeType;
    
                pqiNode->get_nodeType(&nodeType);
    
                switch (nodeType)
    
                {
    
                    case 1:
    
                        bstr = SysAllocString(L"NODE_ELEMENT");
    
                        break;
    
                    case 2:
    
                        bstr = SysAllocString(L"NODE_ATTRIBUTE");
    
                        break;
    
                    case 3:
    
                        bstr = SysAllocString(L"NODE_TEXT");
    
                        break;
    
                    case 7:
    
                        bstr = SysAllocString(L"NODE_PROCESSING_INSTRUCTION");
    
                        break;
    
                    case 8:
    
                        bstr = SysAllocString(L"NODE_COMMENT");
    
                        break;
    
                    case 9:
    
                        bstr = SysAllocString(L"NODE_DOCUMENT");
    
                        break;
    
                }
    
            }
    
            if (bstr)
    
            {
    
                ::OutputDebugString("viewNode->n" + _bstr_t(bstr, false) + "n<-viewNoden");
    
                SysFreeString(bstr);
    
            }
    
        }
    
        catch (...)
    
        {
    
            ::OutputDebugString("viewNode->nException!n<-viewNoden");
    
        }
    
    }
    

    }