Open letter to whoever uses DebuggerStepThroughAttribute

AA+ Coder, would debug again. 

Or not actually. The [DebuggerStepThrough] attribute will, true to its name, instruct debuggers not to step through code contained in the method or constructor it is applied on. This can lead to hours of fun when debugging poorly documented code.

But Florian, you silly monkey, you will see this in the method signature! Will readers interject, to which I would have to reply "not if the method is more than a screen-long and I'm just checking uses of another type/method using Resharper or any fancy code-navigation tool."

The [DebuggerStepThrough] attribute has been there since day 1 of the .Net framework, but should have been kept internal to mscorlib as were 99% of the nice-to-have-but-very-dirty classes that make up most of the .Net framework. This attribute was used to prevent Visual Studio from stepping into the framework and either requesting the source code or treating you to some nice IL. Now of course the .Net framework is released under a shared-source license so you can step through it (most of it, mscorlibs, which accounts dor 75% of the core distribution).

Another misleading friend is the [DebuggerDisplay] attribute, which, when applied on a field or property, will change the name/value reported in the watch window. Apart from cheeky attempts at obfuscation and a slew of practical jokes (turning an int to NaN would be a good one on the top of my head), one would be tempted to use a formatting string with no arguments to protect from famous cases of the debugger auto watch causing side-effects when calling property getters (another form of Heisenbugs).

One way to do this would be :


using System;
using System.Diagnostics;

namespace OneKStrongOxen
{
 public class Runner
 {
  public static void Main(string[] args)
  {
   DebuggerDemo me = new DebuggerDemo();
   Console.Out.WriteLine("Breakpoint set " + me);
  }
 
 }
 class DebuggerDemo
 {
  
  [DebuggerDisplay("These are not the droids you're looking for")]
  public string DangerousProperty
  {
   get
   {
    Console.Out.WriteLine("Property getter invoked with side effects");
    return "DangerousProperty";
   }
  }
 }
}
But sadly, although the display string doesn't contain any reference to the "{DangerousProperty}" format string, the property getter is still invoked...Long story short, if you consider using Debuger*Attribute you're either:

  1. Misled
  2. Overly confidend in the frameworkyness of your code and its quality.
  3. A Microsoft employee working on a non-shared-source API.

One of my current clients used to employ the services of a #2. Emphasis on used.
The solution to the above Heisenbug is either


I prefer the former.

No comments:

Post a Comment

Please leave your comments in English or French and I will be pleased to answer them if you have any questions.

Spammers will be walked down the plank matey. Arrr!