Debugging in Visual Studio: Avoid Stepping Into Common Functions
If you do a lot of debugging (and who doesn't?), you've probably encountered many function calls that you'd really like to step into. Sometimes this is easy: you just hit F11 and waltz right in to the function you care about. Sometimes, however, this is not so easy. In particular, if the code makes function calls to produce arguments for the function:
By Alex Allain
call_of_interest( new blah( "a", 1 ), my_vector.begin(), my_vector.end() );Suddenly, stepping into the function is a huge hassle; first, you're going to need to step through all of the function calls that produce its arguments. How inconvenient; especially when you are absolutely certain that you don't need to--after all, how likely is it that calling my_vector.begin() or your specialized operator new have anything to do with how the function of interest works? Probably not a lot--and if they do, you'll almost certainly be able to tell that they're causing problems by looking at the arguments passed in the function once you've stepped into it.
Sure, you could just set a break point inside the function you're interested in and then hit F5 to continue. But doing that is tedious, especially if you're only interested in one invocation of that function or if you want to step into a lot of functions. In those cases, it's much nicer to simply avoid many of the common functions, such as library functions, that are often invoked to produce inputs for functions.
Various versions of Visual C++ allow you different amounts of control over how you can skip stepping into certain functions, and none of the implementations of this feature are documented or officially supported by Microsoft.
Please note that I cannot guarantee that this functionality will work for you any more than Microsoft will provide that guarantee. Some of the examples require editing the registry; make sure to keep a backup before proceeding!
Visual Studio 6In Visual Studio 6.0, you can edit the file autoexp.dat (which has several other useful features in different versions of Visual Studio), located in "%ProgramFiles%\Microsoft Visual Studio\Common\MSDev98\Bin". In autoexp.dat, different directives appear under different sections named with "[secname]".
To avoid stepping into certain functions, simply add a section, [ExecutionControl], and place under it directives that match either a function name ("myMethod"), a class followed by a method name ("class::method"), or a class followed by a * to skip stepping into all methods of that class ("class::*").
You may need to qualify your classes with their namespaces. Here is an example demonstrating how to avoid stepping into operators; add to autoexp.dat and restart Visual Studio to reload the file:
[ExecutionControl] operator new=NoStepIntoor
Visual Studio 7The debuggers for Visual Studio 7.0 and later read their NoStepInto configuration information from within the registry. You should back up your registry before playing with it. To edit your registry, you'll need to use regedit (just click on Start, go to the run menu, and type in "regedit" and hit enter).
The registry key you'll want to change is
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\NativeDE\StepOverif you're using Visual Studio 2003. You may need to create the keys Native DE its child StepOver. You can do so in RegEdit by navigating to the "VisualStudio\7.0" key and right-clicking and selecting "New->Key".
Inside the StepOver key, you can create new string values that contain regular expressions to match against function names; you can also include a number for the priority of each expression. Using priority, you can set multiple expressions so that you step into a specific function for a class, but skip stepping into all others--higher priority wins when multiple expressions match. For instance, you might have a string with the name and value
20 string\:\:append.*=StepInto 10 string\:\:.*=NoStepIntoIn regular expression parlance, ".*" simply means "match any number of characters". For instance, the second expression matches any function in the string class. (Note that 10 is the name, and everything following it is the value to enter for that name.)
You need to escape the colons because they have special meaning in Visual Studio regular expressions. Similarly, if you wish to match against templates, you need to escape the open and close brackets:
10 .*\<.*\>=StepIntoWhich should always step into any template function.
Visual Studio 8 (2008)Visual Studio 8 has the same basic functionality as Visual Studio 7 with a few improvements. In addition, you should be aware that the key you must modify is now:
HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\NativeDE\StepOverYou'll need an account with Admin privileges to set this up.
In addition to the ability to match regular expressions provided in Visual Studio 7, a few new escape sequences have been added to the regular expressions you can use, including "\funct" to match the name of a function, "\scope" to match a scope (e.g., std::my_namespace::etc::so::forth), and "\oper", which matches any operator. Note that when you use these escape sequences, you must indicate the end of the escape sequence with a colon. So you might write "\scope:" followed by the rest of the expression to match.
For instance, you could avoid stepping into any overloaded operators by using the expression
\scope:operator\oper:=NoStepIntowhich might be useful if you are using a lot of classes with simple operators whose behaviors you can trust to be correct.
Visual Studio 9 (2010)Visual Studio 2010 introduced a few small changes--in particular, you should simply leave out "=NoStepInto" when you want to avoid stepping into a function:
Using "=NoStepInto" will simply not work. Secondly, you can now put your configuration in HKCU, rather than HKLM, allowing you to keep your settings from interfering with other users, but writing to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0_Config\NativeDE\StepOver.
Lastly, I've heard reports that the old syntax using \oper no longer works. A simple workaround is to use:
.*operator.*(Note the ommision of =NoStepInto as well.)
Andy Pennell's Blog
Thanks to Fajen Kyne for pointing out several issues in an earlier version of this article.