Improve StackTraceHiddenAttribute handling (#83)

* Add .NET Core 2.1 as target for tests to allow testing for StackTraceHiddenAttribute handling

* Customize EnhancedStackTrace "hidden" frames selection strategy depending on the runtime, and optimize attribute access for non-reflection-only assemblies

* Add .NET Core 2.1 as target for benchmarks to allow benchmarking for it
This commit is contained in:
Aristarkh Zagorodnikov 2019-02-10 23:50:03 +03:00 committed by Ben Adams
parent 8604340a0e
commit a9830f38e3
3 changed files with 78 additions and 53 deletions

View File

@ -19,6 +19,8 @@ namespace System.Diagnostics
{
public partial class EnhancedStackTrace
{
private static readonly Type StackTraceHiddenAttibuteType = Type.GetType("System.Diagnostics.StackTraceHiddenAttribute", false);
private static List<EnhancedStackFrame> GetFrames(Exception exception)
{
if (exception == null)
@ -645,8 +647,6 @@ namespace System.Diagnostics
private static bool ShowInStackTrace(MethodBase method)
{
Debug.Assert(method != null);
try
{
var type = method.DeclaringType;
if (type == typeof(Task<>) && method.Name == "InnerInvoke")
{
@ -674,12 +674,11 @@ namespace System.Diagnostics
}
}
if (StackTraceHiddenAttibuteType != null)
{
// Don't show any methods marked with the StackTraceHiddenAttribute
// https://github.com/dotnet/coreclr/pull/14652
foreach (var attibute in EnumerableIList.Create(method.GetCustomAttributesData()))
{
// internal Attribute, match on name
if (attibute.AttributeType.Name == "StackTraceHiddenAttribute")
if (IsStackTraceHidden(method))
{
return false;
}
@ -690,15 +689,17 @@ namespace System.Diagnostics
return true;
}
foreach (var attibute in EnumerableIList.Create(type.GetCustomAttributesData()))
if (StackTraceHiddenAttibuteType != null)
{
// internal Attribute, match on name
if (attibute.AttributeType.Name == "StackTraceHiddenAttribute")
// Don't show any types marked with the StackTraceHiddenAttribute
// https://github.com/dotnet/coreclr/pull/14652
if (IsStackTraceHidden(type))
{
return false;
}
}
else
{
// Fallbacks for runtime pre-StackTraceHiddenAttribute
if (type == typeof(ExceptionDispatchInfo) && method.Name == "Throw")
{
@ -723,14 +724,38 @@ namespace System.Diagnostics
return false;
}
}
catch
{
// GetCustomAttributesData can throw
return true;
}
private static bool IsStackTraceHidden(MemberInfo memberInfo)
{
if (!memberInfo.Module.Assembly.ReflectionOnly)
{
return memberInfo.GetCustomAttributes(StackTraceHiddenAttibuteType, false).Length != 0;
}
EnumerableIList<CustomAttributeData> attributes;
try
{
attributes = EnumerableIList.Create(memberInfo.GetCustomAttributesData());
}
catch (NotImplementedException)
{
return false;
}
foreach (var attribute in attributes)
{
// reflection-only attribute, match on name
if (attribute.AttributeType.FullName == StackTraceHiddenAttibuteType.FullName)
{
return true;
}
}
return false;
}
private static bool TryResolveStateMachineMethod(ref MethodBase method, out Type declaringType)
{

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net462</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;netcoreapp2.0;net462</TargetFrameworks>
<Configuration>Release</Configuration>
<OutputType>Exe</OutputType>
</PropertyGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;netcoreapp2.0;net46</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\src\Ben.Demystifier\key.snk</AssemblyOriginatorKeyFile>
<IsPackable>false</IsPackable>