8

I have noticed lately that the Visual Studio 2010 debugger keeps jumping into this method that is marked with the [DebuggerStepThrough] attribute.

Visual Studio 2010 stepping into a DebuggerStepThrough area

The callstack looks something like this:

  1. Page.OnLoad calls a method IsSubclassOfGeneric in a class marked as [DebuggerStepThrough].
  2. IsSubclassOfGeneric calls GetHierarchy as shown, passing a lambda expression to the System.Linq.Enumerable.Any extension.
  3. Visual Studio steps into the method as shown above.

I have just replaced the Linq call with a foreach loop as below, to no avail:

Call to GetHierarchy

This is a bit of an annoyance, since this method is called pretty frequently, and I do not understand why the attribute is being ignored.

Quick Joe Smith
  • 8,074
  • 3
  • 29
  • 33

2 Answers2

3

Try this simple console application, put break points on the lines indicated, run the debugger and on the first break point, press step into (F11). It should miss the second break point. Otherwsie if might be a visual studio setting/extension messing things up.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace tmp {
    class Program {
        static void Main(string[] args) {
            IEnumerable<Type> types = typeof(System.IO.IOException).GetHierarchy(typeof(System.Exception)); //break point here
            int i = 0;
        }
    }
    static class Ext {
        //[DebuggerStepThrough]
        //[DebuggerNonUserCode]
        //[DebuggerStepperBoundary]
        public static IEnumerable<Type> GetHierarchy(this Type type, Type limit) {
            if (type == null) { //break point here
                throw new Exception();
            }
            do {
                yield return type;
                if (type == limit) {
                    yield break;
                }
            } while ((type = type.BaseType) != null);
        }

        [DebuggerStepThrough]
        public static IEnumerable<Type> GetHierarchy2(this Type type, Type limit) {
            if (type == null) { //break point here
                throw new Exception();
            }
            IList<Type> types = new List<Type>();
            do {
                types.Add(type);
                if (type == limit) {
                    break;
                }
            } while ((type = type.BaseType) != null);
            return types;
        }
    }
}

EDIT

Actually i think it has something to do with the yield statement. If i try building a list (GetHierarchy2), i have no problem with the DebuggerStepThrough attribute

djeeg
  • 6,685
  • 3
  • 25
  • 28
  • It certainly does appear that way. I'm frankly amazed that I haven't noticed this sooner. It seems the only other way I can get what I want is to explicitly implement IEnumerable/IEnumerator classes, which is a bit of an annoyance but on the whole might be worth it. – Quick Joe Smith Jan 13 '11 at 11:08
0

Are you debugging a release mode binary? It might be optimized and maybe just deterministic for the compiler at compile time so you won't be able to step in. Take a look at the IL generated and see if this is the case.

Peon the Great
  • 1,289
  • 1
  • 10
  • 17
  • 1
    The problem is that it does step in when I don't want it to. I'm trying to focus on other aspects of the code, and this keeps getting in the way. – Quick Joe Smith Jan 13 '11 at 10:05