diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs
index 28e697b10f..233c509ef0 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs
@@ -172,6 +172,37 @@ namespace Debugger
symReader = metaData.GetSymReader(fullPath, null);
JMCStatus = SymbolsLoaded;
+
+ FindNonUserCode();
+ }
+
+ ///
+ /// Finds all classes and methods marked with DebuggerNonUserCode attribute
+ /// and it marks them for JMC so that they are not stepped into
+ ///
+ void FindNonUserCode()
+ {
+ if (this.SymbolsLoaded) {
+ foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(0, 0)) {
+ MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type);
+ TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType);
+ if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" ||
+ attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute")
+ {
+ if (ca.Owner >> 24 == 0x02) { // TypeDef
+ ICorDebugClass2 corClass = corModule.GetClassFromToken(ca.Owner).CastTo();
+ corClass.SetJMCStatus(0 /* false */);
+ this.Process.TraceMessage("Class {0} marked as non-user code", metaData.GetTypeDefProps(ca.Owner).Name);
+ }
+ if (ca.Owner >> 24 == 0x06) { // MethodDef
+ ICorDebugFunction2 corFunction = corModule.GetFunctionFromToken(ca.Owner).CastTo();
+ corFunction.SetJMCStatus(0 /* false */);
+ MethodProps methodProps = metaData.GetMethodProps(ca.Owner);
+ this.Process.TraceMessage("Function {0}.{1} marked as non-user code", metaData.GetTypeDefProps(methodProps.ClassToken).Name, methodProps.Name);
+ }
+ }
+ }
+ }
}
public void ApplyChanges(byte[] metadata, byte[] il)
diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj
index 95740f7c88..71f83b60a0 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj
+++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj
@@ -26,7 +26,7 @@
DEBUG;TRACE;TEST_CODE
- TRACE
+ TRACE;TEST_CODE
diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebuggerAttributes.cs b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebuggerAttributes.cs
index 7a497e0e6b..aa616d1ea5 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebuggerAttributes.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebuggerAttributes.cs
@@ -17,6 +17,7 @@ namespace Debugger.Tests.TestPrograms
System.Diagnostics.Debug.WriteLine("Start");
System.Diagnostics.Debugger.Break();
Internal();
+ IgnoredClass.Internal();
System.Diagnostics.Debug.WriteLine("End");
}
@@ -25,11 +26,22 @@ namespace Debugger.Tests.TestPrograms
{
System.Diagnostics.Debug.WriteLine("Internal");
}
+
+ [DebuggerNonUserCode]
+ public class IgnoredClass
+ {
+ public static void Internal()
+ {
+ System.Diagnostics.Debug.WriteLine("Internal");
+ }
+ }
}
}
#if TEST_CODE
namespace Debugger.Tests {
+ using NUnit.Framework;
+ using Debugger.Wrappers.CorDebug;
using Debugger.Wrappers.MetaData;
public partial class DebuggerTests
@@ -38,17 +50,13 @@ namespace Debugger.Tests {
public void DebuggerAttributes()
{
StartTest("DebuggerAttributes.cs");
- process.SelectedStackFrame.StepOver();
+
process.SelectedStackFrame.StepInto();
- Module module = process.SelectedStackFrame.MethodInfo.Module;
- foreach(ModuleRefProps mRef in module.MetaData.EnumModuleRefProps()) {
-
- }
- uint typeRef = module.MetaData.FindTypeRef(0, "System.Diagnostics.DebuggerStepThroughAttribute");
- foreach(CustomAttributeProps ca in module.MetaData.EnumCustomAttributeProps(0, 0)) {
- MemberRefProps memProps = module.MetaData.GetMemberRefProps(ca.Type);
- TypeRefProps typeDefProps = module.MetaData.GetTypeRefProps(memProps.DeclaringType);
- }
+ process.SelectedStackFrame.StepInto();
+ Assert.AreEqual(process.SelectedStackFrame.MethodInfo.Name, "Main");
+ process.SelectedStackFrame.StepInto();
+ Assert.AreEqual(process.SelectedStackFrame.MethodInfo.Name, "Main");
+
EndTest();
}
}
@@ -68,8 +76,10 @@ namespace Debugger.Tests {
Start\r\n
Break
StepComplete
+ Internal\r\n
StepComplete
Internal\r\n
+ StepComplete
End\r\n