Debugger Tips, Tricks and Tools #12


I’ve had loads of people ask me the question:


“Is there any way to step into a function without having to bother stepping into all the properties that might have to be executed as parameters before getting to what I’m really interested in?”


The standard answer for Visual Studio 2005 and Visual Studio 2008 has been “well, you probably want to get familiar with the DebuggerStepThrough or DebuggerNonUserCode attributes and use them it in your code.”  However, if it’s not your code that you’re debugging through, or you don’t have the option or would rather not modify it, then this solution isn’t sufficient.


C++ users have had an alternate solution for awhile now.  It’s called Step Into Specific.  The basic idea is that while in the editor the user can right click on a function call to choose from a list of additional function calls that will ultimately be made.  The function call chosen becomes the next stepping point.


Why don’t we have this for managed code debugging?  The short answer is that this type of solution requires support from the .NET runtime. This support is not in .NET 2.0, nor is it in the runtime that will ship with VS 2008 (which is basically mainly an extension of the core 2.0 runtime).


What’s a managed programmer to do then?  Curse and swear.  Or perhaps try to find a workaround.  That’s where this article comes in. I’ve created a macro called StepIntoHere().  It analyzes the code on which the editor caret is currently positioned and then attempts to simulate a “step-into” exactly the code that implements that function, bypassing any other function calls or properties that have to be made along the way.


For example, say you have this code: 


           CoolClass c = new CoolClass();


           c.DoSomething(new UnCoolClass().MyProp);


This macro allows you to place the caret on “DoSomething” and then do a step into the “DoSomething” function directly rather than having to first step into the constructor for “UnCoolClass” and then it’s “MyProp” property. 


Sounds great, and it seems to work quite well for trivial applications I’ve tried it with.  I’m not too sure how well it works for much larger apps, but I’m hoping this blog will help me find out.


(See my Idiot’s Guide for creating and using VS Macros for quick and easy steps on how to add this macro to VS.  To make it more like the C++ version, add it to the Editor’s context menu. For extra credit, add an image for it by copying and pasting the existing step-into icon and modifying it slightly.  This can be done while customizing your context menu… hint: right click 🙂 )


Sub StepIntoHere()


        If DTE.Debugger Is Nothing Or DTE.Debugger.CurrentMode <> dbgDebugMode.dbgBreakMode Then


            Beep()


        Else


            Dim textSelection As EnvDTE.TextSelection = DTE.ActiveWindow.Selection


            If textSelection.IsEmpty Then


                textSelection.WordLeft(False)


                textSelection.WordRight(True)


            End If


 


            textSelection = DTE.ActiveWindow.Selection


            Dim bp As EnvDTE.Breakpoint


            Dim bps As EnvDTE.Breakpoints


            bps = DTE.Debugger.Breakpoints.Add(textSelection.Text)


 


            ‘If we have at least one bound breakpoint, go, otherwise just do a step-into.


            If bps.Count > 0 And bps.Item(1).Children.Count > 0 Then


                DTE.Debugger.Go()


            Else


                DTE.Debugger.StepInto()


            End If


 


            ‘ Unselect what we selected.


            textSelection = Nothing


 


            ‘ Delete the breakpoints we created.


            For Each bp In bps


                bp.Delete()


            Next


        End If


    End Sub


 

Comments (3)

  1. Roger Wolff says:

    Just because I am curious…can you explain the long answer for “The short answer is that this type of solution requires support from the .NET runtime.”?

    This functionality seems useful, and I don’t understand why it couldn’t be done with existing CLR functionality.  It seems like VS could do something very similar to what your macro is doing (or perhaps even easier with setting a single breakpoint before the call, and then issuing a step in), and keeping track of all kinds of good debugger state (maybe keeping the breakpoint hidden, or not stopping if that breakpoint gets hit from a different thread, etc…)

  2. Greazer says:

    What I was referring to was the ability to exactly replicate the behavior and *general  implementation* that is done by native C++.  However, after talking about it a bit more my team decided that it might be doable without changes to the CLR.  However, we also questioned whether that was the right solution anyway.

    That being said the macro I presented is closer to what I think developers would want…  even native C++ developers.  So we are considering features along these lines in a future version of VS.

    Further comments are welcome.

  3. davidbak@gmail.com says:

    Speaking of ‘Step Into Specific’ – one of the greatest unknown features of the VC++ debugger:  It isn’t assigned a keyboard shortcut, probably because it just pops up a submenu and doesn’t have a real UI.  So – being that I am totally lame at writing a VS macro – how would you write a macro to pop up the menu system with "Step Into Specific" highlighted and the fly-out-popup-menu out, ready to select an item with the arrow keys?  Thanks!