BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Debugging
.NET 2.0

Marking Non-User Code

Visual Studio's debugger considers several variables when determining how to step through code and react to breakpoints. One such item is code that has been flagged as non-user code. This is automatically stepped over and excluded from the call stack display.

Non-User Code

When you create a solution using Visual Studio, the source code usually contains a combination of code that you type yourself and elements that are automatically generated by the integrated development environment (IDE). When debugging, the debugger usually automatically steps through the generated, non-user code, hiding it so that the process and the displayed information are less complicated.

If your development processes include generating code using external tools, it can be useful to hide such code from the debugger in a similar manner. In previous articles I've explained how this can be achieved using the DebuggerHidden and DebuggerStepThrough attributes. However, these attributes have limitations that mean that they cannot always be applied in a suitable manner.

Another debugger attribute, introduced with the .NET framework version 2.0, addresses some of these issues. The DebuggerNonUserCode attribute combines the features of the above two attributes. Like DebuggerHidden, it hides flagged items from the call stack. As with DebuggerStepThrough, it causes the debugger to automatically step over the hidden items, ignoring any breakpoints within non-user code. In addition, DebuggerNonUserCode can be applied in a wider variety of situations. You can hide entire classes or structures, as well as marking individual methods, properties and constructors.

Finally, non-user code is compatible with Visual Studio's "Just My Code" feature. This allows you to tell the debugger to ignore the attribute and step into non-user code when required, without the need to remove the attribute.

To demonstrate, create a new console application project. To simplify access to the attribute, add the following using directive to the top of the file containing the Main method:

using System.Diagnostics;

Replace the Main method with the following three members:

static void Main(string[] args)
{
    DoSomething();
}

[DebuggerNonUserCode]
static void DoSomething()
{
    Console.WriteLine("Can't step into this");
    DoSomethingElse();
}

static void DoSomethingElse()
{
    Console.WriteLine("Can step into this");
}

The code in the Main method calls DoSomething. This outputs a message to the console before calling DoSomethingElse, which displays another string. As DoSomething is marked with the DebuggerNonUserCode attribute, it is ignored by the debugger. If you step through the code, when the call to DoSomething is encountered, control is passed directly to DoSomethingElse. At this point, the call stack window shows only DoSomethingElse and Main.

NB: The use of the attribute has no effect on the operation of the program.

13 October 2015