Make Exception.StackTrace resilient to missing attribute assemblies (#48535)
authorJan Vorlicek <jan.vorlicek@volny.cz>
Wed, 24 Feb 2021 21:33:09 +0000 (13:33 -0800)
committerGitHub <noreply@github.com>
Wed, 24 Feb 2021 21:33:09 +0000 (22:33 +0100)
A customer has reported a problem when they could not get stack trace
from an exception that they needed to log, because one of the methods on
the stack or its defining type had an attribute from an assembly that
was missing.
This change fixes that by ignoring exceptions in attempts to get
StackTraceHiddenAttribute, preferring to err on the side of getting a
stack frame that was marked as hidden in the stack trace rather than
not getting any stack trace at all.

src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs

index 72858d2..3c6ba96 100644 (file)
@@ -354,19 +354,28 @@ namespace System.Diagnostics
                 return false;
             }
 
-            if (mb.IsDefined(typeof(StackTraceHiddenAttribute), inherit: false))
+            try
             {
-                // Don't show where StackTraceHidden is applied to the method.
-                return false;
-            }
+                if (mb.IsDefined(typeof(StackTraceHiddenAttribute), inherit: false))
+                {
+                    // Don't show where StackTraceHidden is applied to the method.
+                    return false;
+                }
 
-            Type? declaringType = mb.DeclaringType;
-            // Methods don't always have containing types, for example dynamic RefEmit generated methods.
-            if (declaringType != null &&
-                declaringType.IsDefined(typeof(StackTraceHiddenAttribute), inherit: false))
+                Type? declaringType = mb.DeclaringType;
+                // Methods don't always have containing types, for example dynamic RefEmit generated methods.
+                if (declaringType != null &&
+                    declaringType.IsDefined(typeof(StackTraceHiddenAttribute), inherit: false))
+                {
+                    // Don't show where StackTraceHidden is applied to the containing Type of the method.
+                    return false;
+                }
+            }
+            catch
             {
-                // Don't show where StackTraceHidden is applied to the containing Type of the method.
-                return false;
+                // Getting the StackTraceHiddenAttribute has failed, behave as if it was not present.
+                // One of the reasons can be that the method mb or its declaring type use attributes
+                // defined in an assembly that is missing.
             }
 
             return true;