Skip to content

Instantly share code, notes, and snippets.

@jaredpar
Last active July 23, 2024 18:25
Show Gist options
  • Save jaredpar/3e6eb325ac745fde15e4ab09dafa598a to your computer and use it in GitHub Desktop.
Save jaredpar/3e6eb325ac745fde15e4ab09dafa598a to your computer and use it in GitHub Desktop.

Summary

Build Status Query

  • Ignore results from aspnetcore-quaritined-pr as they don't upload binlogs.
  • Ignore results form aspnetcore-ci as they overwrite logs on retry.

Investigation Next Steps

To investigate we need change our builds to have the following property:

<Features>$(Features);debug-analyzers</Features>

This will cause the compiler to FailFaist when it hits an analyzer exception (default behavior is catch and report). This is done in the catch filter so it will provide us with actionable crash dumps. Next the builds should also set a combination of the following set:

> export DOTNET_DbgEnableMiniDump=1
> export DOTNET_DbgMiniDumpType=2
> export DOTNET_DbgMiniDumpName=/path/to/artifacts/logs/Release/%p.dmp

Finally the pipeline needs to make sure those dumps are uploaded when available.

Cases

DetectPreviewFeatureAnalyzer (ConcurrentDictionary NRE)

Stack Trace

System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Concurrent.ConcurrentDictionary`2.TryRemoveInternal(TKey key, TValue& value, Boolean matchValue, TValue oldValue)
at Microsoft.CodeQuality.Analyzers.Maintainability.AvoidUnusedPrivateFieldsAnalyzer.<>c__DisplayClass5_0.<Initialize>b__2(OperationAnalysisContext operationContext)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken)

That almost certainly represents this line in code:

IFieldSymbol field = ((IFieldReferenceOperation)operationContext.Operation).Field;
if (field.DeclaredAccessibility == Accessibility.Private)
{
    referencedPrivateFields.TryAdd(field, default);
    // Error is here. 
    maybeUnreferencedPrivateFields.TryRemove(field, out _);
}

Both values here are non-null:

  • maybeUnreferencedPrivateFields: is single assign and initialized to non-null at declaration
  • field: is used above this line several times without null reffing.

Seems to either be a libraries or codegen bug.

Alternate stack trace with similar "can't be null input" characteristics

System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Concurrent.ConcurrentDictionary`2.TryGetValue(TKey key, TValue& value)
at Microsoft.NetCore.Analyzers.Runtime.DetectPreviewFeatureAnalyzer.SymbolIsAnnotatedAsPreview(ISymbol symbol, ConcurrentDictionary`2 requiresPreviewFeaturesSymbols, INamedTypeSymbol previewFeatureAttribute)
at Microsoft.NetCore.Analyzers.Runtime.DetectPreviewFeatureAnalyzer.AnalyzeSymbol(SymbolAnalysisContext context, ConcurrentDictionary`2 requiresPreviewFeaturesSymbols, IFieldSymbol virtualStaticsInInterfaces, INamedTypeSymbol previewFeatureAttributeSymbol)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken)

Instances:

DetectPreviewFeatureAnalyzer (IOperation)

Stack Trace

Exception occurred with following context:
Compilation: Microsoft.CodeAnalysis.Razor.Compiler
IOperation: Invocation
SyntaxTree: /vmr/src/razor/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Syntax.Generated.cs
SyntaxNode: GetAnnotations() [InvocationExpressionSyntax]@[6078..6094) (208,30)-(208,46)
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.NetCore.Analyzers.Runtime.DetectPreviewFeatureAnalyzer.GetOperationSymbol(IOperation operation)
at Microsoft.NetCore.Analyzers.Runtime.DetectPreviewFeatureAnalyzer.OperationUsesPreviewFeatures(OperationAnalysisContext context, ConcurrentDictionary`2 requiresPreviewFeaturesSymbols, INamedTypeSymbol previewFeatureAttributeSymbol, ISymbol& referencedPreviewSymbol)
at Microsoft.NetCore.Analyzers.Runtime.DetectPreviewFeatureAnalyzer.<>c__DisplayClass33_0.<Initialize>b__1(OperationAnalysisContext context)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken)

That is basically down to this block of code. That code on it's own (no inlining) is very hard to see a NRE on. Suspect that there is some amount of inlining going on here.

The invocation being analyzed here is the GetAnnotations() call on this line. That means we should be at this point in the code

        private static ISymbol? GetOperationSymbol(IOperation operation)
            => operation switch
            {
                // EXECUTION SHOULD BE HERE
                IInvocationOperation iOperation => iOperation.TargetMethod,
                IObjectCreationOperation cOperation => cOperation.Constructor,

Basically that should be an InvocationOperation and given that it's sealed and only impl of IInvocationOperation it is likely a candidate for inlining. At the same time the TargetMethod is an auto-implemented property and shouldn't ever null ref itself.

This a very puzzling one to understand. Seems like another case we'd need the debug-analyzers flag to get a dump and track down.

Instances

SpecifyIFormatProvider

Stack Trace

IOperation: Invocation
SyntaxTree: /vmr/src/vstest/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs
SyntaxNode: managedTypeName.Substring(hierarchyPos ... [InvocationExpressionSyntax]@[10118..10203) (200,68)-(200,153)
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.NetCore.Analyzers.Runtime.SpecifyIFormatProviderAnalyzer.<>c__DisplayClass13_0.<InitializeWorker>b__0(OperationAnalysisContext oaContext)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken)

That block of code is a lot bigger. Harder to say it's definitely null safe. At the same time the logic in that code is very straight forward. This could be a bug in the compiler where we have a race that returns a null.

Instances

DiagnosticDescriptorCreationAnalyzer

Stack Trace

CSC error AD0001: Analyzer 'Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers.DiagnosticDescriptorCreationAnalyzer' threw an exception of type 'System.InvalidCastException' with message 'Unable to cast object of type 'Node[Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer,System.Runtime.CompilerServices.StrongBox`1[Microsoft.CodeAnalysis.Diagnostics.AnalyzerActions]]' to type 'Microsoft.CodeAnalysis.INamedTypeSymbol'.'. [/vmr/src/razor/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Microsoft.AspNetCore.Razor.LanguageServer.csproj]
ISymbol: CompletionListMerger (NamedType)
System.InvalidCastException: Unable to cast object of type 'Node[Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer,System.Runtime.CompilerServices.StrongBox`1[Microsoft.CodeAnalysis.Diagnostics.AnalyzerActions]]' to type 'Microsoft.CodeAnalysis.INamedTypeSymbol'.
at Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers.DiagnosticDescriptorCreationAnalyzer.<>c__DisplayClass25_1.<Initialize>b__6(SymbolAnalysisContext context)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken)

That is this block of code. This fees like a potential compiler bug ... still weird it's non-determinstic failure.

Instances

UseThreadStaticCorrectly

Stack Trace

Compilation: Microsoft.Data.Sqlite
ISymbol: _record (Field)
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c.<ExecuteSymbolActions>b__45_1(ValueTuple`2 data)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken)

The error is actually in the AnalyzerExecutor seemingly trying to call into this block of code. The exception being rooted in the AnalyzerExecutor is strange though. It's almost certainly at this block which is very hard to see a NRE on.

Instances:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment