From a64a6e7e6ee2cb983682251675a71f81a4e44a96 Mon Sep 17 00:00:00 2001 From: Luqun Lou Date: Mon, 18 Jun 2018 13:24:48 -0700 Subject: [PATCH] Add public implementation WindowsRuntime ExceptionSupport (dotnet/coreclr#18494) Commit migrated from https://github.com/dotnet/coreclr/commit/d4bbfb39572a2e1cb0708c7c94d0c05aee69d813 --- .../System.Private.CoreLib.csproj | 1 + .../WindowsRuntime/ExceptionSupport.cs | 79 ++++++++++++++++++++++ .../System.Private.CoreLib/src/System/Exception.cs | 1 - .../WindowsRuntime/WindowsRuntimeMarshal.cs | 1 - 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs diff --git a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj index 419d1cc..a97fa08 100644 --- a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -302,6 +302,7 @@ + diff --git a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs new file mode 100644 index 0000000..1772105 --- /dev/null +++ b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices.WindowsRuntime; + +namespace Internal.Runtime.InteropServices.WindowsRuntime +{ + public static class ExceptionSupport + { + /// + /// Attach restricted error information to the exception if it may apply to that exception, returning + /// back the input value + /// + public static Exception AttachRestrictedErrorInfo(Exception e) + { + // If there is no exception, then the restricted error info doesn't apply to it + if (e != null) + { + try + { + // Get the restricted error info for this thread and see if it may correlate to the current + // exception object. Note that in general the thread's IRestrictedErrorInfo is not meant for + // exceptions that are marshaled Windows.Foundation.HResults and instead are intended for + // HRESULT ABI return values. However, in many cases async APIs will set the thread's restricted + // error info as a convention in order to provide extended debugging information for the ErrorCode + // property. + IRestrictedErrorInfo restrictedErrorInfo = UnsafeNativeMethods.GetRestrictedErrorInfo(); + if (restrictedErrorInfo != null) + { + string description; + string restrictedDescription; + string capabilitySid; + int restrictedErrorInfoHResult; + restrictedErrorInfo.GetErrorDetails(out description, + out restrictedErrorInfoHResult, + out restrictedDescription, + out capabilitySid); + + // Since this is a special case where by convention there may be a correlation, there is not a + // guarantee that the restricted error info does belong to the async error code. In order to + // reduce the risk that we associate incorrect information with the exception object, we need + // to apply a heuristic where we attempt to match the current exception's HRESULT with the + // HRESULT the IRestrictedErrorInfo belongs to. If it is a match we will assume association + // for the IAsyncInfo case. + if (e.HResult == restrictedErrorInfoHResult) + { + string errorReference; + restrictedErrorInfo.GetReference(out errorReference); + + e.AddExceptionDataForRestrictedErrorInfo(restrictedDescription, + errorReference, + capabilitySid, + restrictedErrorInfo); + } + } + } + catch + { + // If we can't get the restricted error info, then proceed as if it isn't associated with this + // error. + } + } + + return e; + } + + /// + /// Report that an exception has occurred which went user unhandled. This allows the global error handler + /// for the application to be invoked to process the error. + /// + /// true if the error was reported, false if not (ie running on Win8) + public static bool ReportUnhandledError(Exception ex) + { + return WindowsRuntimeMarshal.ReportUnhandledError(ex); + } + } +} diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Exception.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Exception.cs index daa687d..3ba1fdc 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Exception.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Exception.cs @@ -183,7 +183,6 @@ namespace System } } - // [FriendAccessAllowed] internal void AddExceptionDataForRestrictedErrorInfo( string restrictedError, string restrictedErrorReference, diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs index 521ad9d..7a4fef5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs @@ -1122,7 +1122,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime /// for the application to be invoked to process the error. /// /// true if the error was reported, false if not (ie running on Win8) - // [FriendAccessAllowed] internal static bool ReportUnhandledError(Exception e) { // Only report to the WinRT global exception handler in modern apps -- 2.7.4