From 7ca24e2c2c1a4276ada58af04e1d70857fe3c7b5 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Fri, 12 Jul 2024 10:26:04 -0700 Subject: [PATCH 1/3] Add DebuggerDisableUserUnhandledExceptionsAttribute - Also add Debugger.BreakForUserUnhandledException(Exception) --- .../src/System/Diagnostics/Debugger.cs | 11 +++++++++++ .../src/System.Private.CoreLib.Shared.projitems | 3 ++- ...ggerDisableUserUnhandledExceptionsAttribute.cs | 15 +++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 6 ++++++ .../src/System/Diagnostics/Debugger.cs | 4 ++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Diagnostics/DebuggerDisableUserUnhandledExceptionsAttribute.cs diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 9a51c47cb020e..bdbdb2dbd3b02 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -91,5 +91,16 @@ public static extern bool IsAttached // report the notification depending on its settings. [MethodImpl(MethodImplOptions.InternalCall)] private static extern void CustomNotification(ICustomDebuggerNotification data); + + /// + /// If a .NET Debugger is attached with break on user-unhandled exception enabled and a method attributed with + /// DebuggerDisableUserUnhandledExceptionsAttribute calls this method, the debugger will break with the + /// details. + /// + /// The user-unhandled exception. + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + public static void BreakForUserUnhandledException(Exception exception) + { + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 1ed17ee58cde7..e411ea840b88e 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -293,6 +293,7 @@ + @@ -2800,4 +2801,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/DebuggerDisableUserUnhandledExceptionsAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/DebuggerDisableUserUnhandledExceptionsAttribute.cs new file mode 100644 index 0000000000000..9da4dae623afc --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/DebuggerDisableUserUnhandledExceptionsAttribute.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics +{ + /// + /// If a .NET Debugger is attached which supports the Debugger.BreakForUserUnhandledException(Exception) API, + /// this attribute will prevent the debugger from breaking on user-unhandled exceptions when the + /// exception is caught by a method with this attribute, unless BreakForUserUnhandledException is called. + /// + [AttributeUsage(AttributeTargets.Method)] + public sealed class DebuggerDisableUserUnhandledExceptionsAttribute : Attribute + { + } +} diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index e7e61105315e0..30bf73b20b860 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8666,6 +8666,7 @@ public static partial class Debugger public static readonly string? DefaultCategory; public static bool IsAttached { get { throw null; } } public static void Break() { } + public static void BreakForUserUnhandledException(Exception exception) { } public static bool IsLogging() { throw null; } public static bool Launch() { throw null; } public static void Log(int level, string? category, string? message) { } @@ -8683,6 +8684,11 @@ public enum DebuggerBrowsableState Collapsed = 2, RootHidden = 3, } + [AttributeUsage(AttributeTargets.Method)] + public sealed class DebuggerDisableUserUnhandledExceptionsAttribute : Attribute + { + public DebuggerDisableUserUnhandledExceptionsAttribute() { } + } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Delegate | System.AttributeTargets.Enum | System.AttributeTargets.Field | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple=true)] public sealed partial class DebuggerDisplayAttribute : System.Attribute { diff --git a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 6d3593b6e05e4..efb610d19ac5f 100644 --- a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -41,5 +41,9 @@ public static void Log(int level, string? category, string? message) public static void NotifyOfCrossThreadDependency() { } + + public static void BreakForUserUnhandledException(Exception exception) + { + } } } From c40912d3cf2ca22d9b891d7c24db9c8057d0118b Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Fri, 12 Jul 2024 11:01:59 -0700 Subject: [PATCH 2/3] Add BreakForUserUnhandledException to nativeaot Debugger class --- .../src/System/Diagnostics/Debugger.cs | 11 +++++++++++ .../src/System/Diagnostics/Debugger.cs | 1 + 2 files changed, 12 insertions(+) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 7f0fa52f98825..0fbba0e5aaf28 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -74,5 +74,16 @@ public static bool IsLogging() } return false; } + + /// + /// If a .NET Debugger is attached with break on user-unhandled exception enabled and a method attributed with + /// DebuggerDisableUserUnhandledExceptionsAttribute calls this method, the debugger will break with the + /// details. + /// + /// The user-unhandled exception. + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + public static void BreakForUserUnhandledException(Exception exception) + { + } } } diff --git a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index efb610d19ac5f..19cda4f517bab 100644 --- a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -42,6 +42,7 @@ public static void NotifyOfCrossThreadDependency() { } + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void BreakForUserUnhandledException(Exception exception) { } From 90c9123cc8cee64e0becf235b74ee0174bf8ece1 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Fri, 12 Jul 2024 12:49:11 -0700 Subject: [PATCH 3/3] Address PR feedback --- .../src/System/Diagnostics/Debugger.cs | 11 ---------- .../src/System/Diagnostics/Debugger.cs | 13 +----------- .../System.Private.CoreLib.Shared.projitems | 1 + .../src/System/Diagnostics/Debugger.cs | 21 +++++++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 6 +++--- .../src/System/Diagnostics/Debugger.cs | 7 +------ 6 files changed, 27 insertions(+), 32 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index bdbdb2dbd3b02..9a51c47cb020e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -91,16 +91,5 @@ public static extern bool IsAttached // report the notification depending on its settings. [MethodImpl(MethodImplOptions.InternalCall)] private static extern void CustomNotification(ICustomDebuggerNotification data); - - /// - /// If a .NET Debugger is attached with break on user-unhandled exception enabled and a method attributed with - /// DebuggerDisableUserUnhandledExceptionsAttribute calls this method, the debugger will break with the - /// details. - /// - /// The user-unhandled exception. - [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] - public static void BreakForUserUnhandledException(Exception exception) - { - } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 0fbba0e5aaf28..a0106b1816ec5 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -5,7 +5,7 @@ namespace System.Diagnostics { - public static class Debugger + public static partial class Debugger { [MethodImpl(MethodImplOptions.NoInlining)] [DebuggerHidden] // this helps VS appear to stop on the source line calling Debugger.Break() instead of inside it @@ -74,16 +74,5 @@ public static bool IsLogging() } return false; } - - /// - /// If a .NET Debugger is attached with break on user-unhandled exception enabled and a method attributed with - /// DebuggerDisableUserUnhandledExceptionsAttribute calls this method, the debugger will break with the - /// details. - /// - /// The user-unhandled exception. - [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] - public static void BreakForUserUnhandledException(Exception exception) - { - } } } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index e411ea840b88e..b3b90438282b5 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -292,6 +292,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs new file mode 100644 index 0000000000000..77e97ba62f465 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +namespace System.Diagnostics +{ + public static partial class Debugger + { + /// + /// Signals a breakpoint to an attached debugger with the details + /// if a .NET debugger is attached with break on user-unhandled exception enabled and a method + /// attributed with DebuggerDisableUserUnhandledExceptionsAttribute calls this method. + /// + /// The user-unhandled exception. + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + public static void BreakForUserUnhandledException(Exception exception) + { + } + } +} diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 30bf73b20b860..db837e955d134 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8666,7 +8666,7 @@ public static partial class Debugger public static readonly string? DefaultCategory; public static bool IsAttached { get { throw null; } } public static void Break() { } - public static void BreakForUserUnhandledException(Exception exception) { } + public static void BreakForUserUnhandledException(System.Exception exception) { } public static bool IsLogging() { throw null; } public static bool Launch() { throw null; } public static void Log(int level, string? category, string? message) { } @@ -8684,8 +8684,8 @@ public enum DebuggerBrowsableState Collapsed = 2, RootHidden = 3, } - [AttributeUsage(AttributeTargets.Method)] - public sealed class DebuggerDisableUserUnhandledExceptionsAttribute : Attribute + [System.AttributeUsage(System.AttributeTargets.Method)] + public sealed class DebuggerDisableUserUnhandledExceptionsAttribute : System.Attribute { public DebuggerDisableUserUnhandledExceptionsAttribute() { } } diff --git a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs index 19cda4f517bab..ccd8fb6d75ed1 100644 --- a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs +++ b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs @@ -5,7 +5,7 @@ namespace System.Diagnostics { - public static class Debugger + public static partial class Debugger { public static readonly string? DefaultCategory; @@ -41,10 +41,5 @@ public static void Log(int level, string? category, string? message) public static void NotifyOfCrossThreadDependency() { } - - [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] - public static void BreakForUserUnhandledException(Exception exception) - { - } } }