Improve your debugging: Debugging Attributes to make your life easier
July 25, 2008 7:27 pm .Net, Improve Your Code, Visual StudioDuring my recent talk on CLR Production Debugging I’ve talked about several interesting attributes that you introduce in your code to make debugging easier. Here is a review of these attributes:
Debugging support attributes
DebuggerStepThroughAttribute & DebuggerNonUserCodeAttrbute
Both attributes do about the same thing: they informs the debugger to not step into that class during normal “Step-Into” debugging. They are generally used on generated code or framework code to avoid the pain on getting into a method that you don’t care about while you debug.
There are very subtle differences between the two attributes:
- DebuggerStepThroughAttribute
- Can be applied to Classes, Structs, Constructors and Methods
- Will not step into the method on “Step Into” through the debugger, but allows you to set a breakpoint in the method and the debugger will stop at that breakpoint.
- DebuggerNonUserCodeAttrbute
- Can be applied to Classes, Structs, Constructors, Methods and Properties
- Will not step into the method at all even if you have a breakpoint setup or an exception is raised
Sample:
The debugger will not enter in any method declared in this class:
[DebuggerStepThrough()] public static class ConfigUtils { [...] }
Debugging enhancement attributes
Enhancements attributes are attributes that have no meaning for the CLR but are used by the debugger to improve the way the type/variable is displayed when you look at it in the debugger.
DebuggerDisplayAttribute
Changes the way the class is rendered in the debugger. In the declaration of the attribute you can include multiple properties or fields of you class to be displayed and even call methods on your class and render the result.
You can also include properties or fields of your member properties/fields and your class.
This attribute can be applied to basically almost every construct (classes, structs, enums, fields, properties, delegates and assemblies).
The attribute also supports display based on conditions and basic formatting like “nq” used to strip away quotes from strings.
Samples:
[DebuggerDisplay("Id={id} Name={firstName} {lastName}")] public class Customer { private int id; private string firstName; private string lastName;
No attributes applied:
Applying the attribute will display:
The following attribute:
[DebuggerDisplay("Id={id} Name={firstName, nq} {lastName, nq} Orders={Orders.Count}")]
Renders this:
More details can be found on the MSDN page Using DebuggerDisplay Attribute.
DebuggerBrowsableAttribute
The attribute can be used to let the debugger know how to display (or not to display) specified fields or properties of your class.
For example setting [DebuggerBrowsable(DebuggerBrowsableState.Never)] will make the field invisible in the watch of data tips of the debugger. This is especially useful when you have fields that are exposed as properties and you don’t want to see them twice in the debugger:
Sample:
public class Customer { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int id; public int Id { get { return id; } set { id = value; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string firstName; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string lastName;
No attributes applied will render this:
(you can see both the fields and the properties)
Applying the attributes will render this:
(only the public properties are visible)
Several other attributes worth having a look at are:
- DebuggerTypeProxyAttribute – allows to specify a proxy class that will be used to display your type. The debugger will instantiate the proxy and ask it to render your class. Can be very valuable when you want to look at complex classes.
- DebuggerVisualizerAttribute – allows you to specify a class to be used to visualize your type.
Happy debugging.
Update: 25/07/2008 20:50: You can see a quick screen-cast of using these attributes here: http://www.acorns.com.au/files/VS_Debugging_Tips_Attributes.wmv (10.6Mb)
July 26th, 2008 at 5:30 pm
These attributes are indeed useful when writing framework code. You can significantly improve the debugging experience with a little extra work.
The DebuggerHiddenAttribute is also quite handy. Among other things, MbUnit v3 filters stack traces in test failure messages based on the presence of this attribute and a couple of others.
Filtering can significantly reduce the cognitive load for grokking the failure because irrelevant internal (and assumed correct) implementation details are hidden. For example, it’s not terribly useful to see the intermediate stack frames involved in MethodBase.Invoke() and other constructs that the BCL and test framework use.
July 28th, 2008 at 6:29 am
I’ve overridden ToString() more than a few times to try to customize my debugger visualization but this is clearly a much better way to do it!
I’ll be using these. Thanks.
July 28th, 2008 at 2:21 pm
[...] it out on his blog http://www.acorns.com.au/blog/?p=128 [...]
July 29th, 2008 at 9:52 am
You did a fantastic session in Melbourne the other night. When will the powerpoint slides be available from your talk?
July 29th, 2008 at 11:23 pm
Michael,
Thanks for the nice words. I planned to post it during last weekend but was too busy. I’ll try to do it soon as I have to do a proper blog post with it.
Regards,
Corneliu
August 20th, 2008 at 5:17 am
[...] info By Roman Hnatiuk Categories: .Net and Debugging Improve your debugging: Debugging Attributes to make your life easier post talkes about several interesting attributes that make debugging easier - [...]