Roslyn: Exception An unhandled exception of type 'System.StackOverflowException' occurred in Microsoft.CodeAnalysis.CSharp.dll

Created on 12 Jun 2018  路  6Comments  路  Source: dotnet/roslyn

Version Used:
2.8.2
Steps to Reproduce:

  1. We are trying to do CSharpSyntaxWalker on open source corert-master [https://github.com/dotnet/corert.git] code.
  2. During the CSharpSyntax walk, we are trying to extract the information for VisitMemberAccessExpression like below:

    ```
    SemanticModel sementicModel = document.GetSemanticModelAsync().Result;
    .....
    .....
    .....

    public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
    {
       //The below check is for that specific code walk for which we get the exception.
        if(node.ToFullString().Contains("RuntimeImports.RhpRegisterFrozenSegment"))
        {
    
        }
        var multiIdentifierName = node.ChildNodes()
                .Where(x => x.IsKind(SyntaxKind.IdentifierName)).ToList();
        {
            foreach (var identifierNode in multiIdentifierName)
            {
                try
                {
                    var symbolInfo = semanticModel.GetSymbolInfo(identifierNode).Symbol
                                            ?? semanticModel.GetDeclaredSymbol(identifierNode);
                }
                catch(System.StackOverflowException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }
    
3. In the **corert-master** code, there is a file **StartupCodeHelpers.cs** at location **..\corert-master\src\Common\src\Internal\Runtime\CompilerHelpers\StartupCodeHelpers.cs**. 
4. In this file, there is a MemberAccessExpression at line number **176** with following code:
        if (!RuntimeImports.RhpRegisterFrozenSegment(segmentStart, length))
        {
            // This should only happen if we ran out of memory.
            RuntimeExceptionHelpers.FailFast("Failed to register frozen object segment.");
        }

```

  1. When our code tries to get the symbol information for RuntimeImports.RhpRegisterFrozenSegment using semanticModel using the above code, the thread stops immediately and the walker application breaks.

Expected Behavior:
The resolution of symbol information should not break in this case. The code should continue with proper resolution.

Actual Behavior:
Exception An unhandled exception of type 'System.StackOverflowException' occurred in Microsoft.CodeAnalysis.CSharp.dll

The maximum number of stack frames supported by Visual Studio has been exceeded.

Additional observation

  1. If we look at the RuntimeImports file, we can see that the method RhpRegisterFrozenSegment has no definition. It just has a declaration.
  2. In the same file, we can see couple of other methods like RhGetModuleSection have declaration and definition and for such calls RuntimeImports.RhGetModuleSection say at line 166 under file StartupCodeHelpers.cs, the symbol resolution happens successfully.

Please find a source code of walker attached which runs over corert-master code and reproduces the issue. The code is written using VS 2017 and .NET Framework 4.7.

Roslyn_CoreRt_Run.zip

Area-Compilers Bug

All 6 comments

@abhijitparkhi1983 Thanks for reporting this.
Would you be able to share a dump file for the overflow? Hopefully it's not too large and we can exchange it via some online drive (Dropbox/OneDrive/...).

Assuming the application crashes, you can get Windows to produce a dump file for the dying process with a simple configuration.
If the crash occurs while you're debugging, you can use Visual Studio to save a dump file (with heap please).

@jcouv thanks for a quick revert.

I have shared the required dump with heap at [https://www.dropbox.com/s/5lno9rri5j8vtr2/Roslyn_CoreRT_Run.zip?dl=0]

The dump has been created while debugging through VS 2017 Community Version.
Also, the code which I had attached is a working copy. So if the dump I have provided gives no better insights in the issue, i request you to run the attached code at your end on the said repo. This might give a much better dump results i guess.

Looking forward to further updates on this front.

That dump file was enormously helpful. Thanks!

The problem is related to using IndexNameAttribute on a property/indexer.
```C#
[System.Runtime.CompilerServices.IndexerName("Chars")]
public unsafe char this[int index]
{

if PROJECTN

        [BoundsChecking]
        get
        {
            return Unsafe.Add(ref _firstChar, index);
        }

else

        [Intrinsic]
        get
        {
            if ((uint)index >= _stringLength)
                ThrowHelper.ThrowIndexOutOfRangeException();
            return Unsafe.Add(ref _firstChar, index);
        }

endif

    }

Here's the repeating portion of the stack trace:

Symbols.SourcePropertySymbol.SourcePropertySymbol(Symbols.SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, Syntax.BasePropertyDeclarationSyntax syntax, string name, Microsoft.CodeAnalysis.Location location, Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 94 C#
Symbols.SourcePropertySymbol.Create(Symbols.SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, Syntax.IndexerDeclarationSyntax syntax, Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 459 C#
Symbols.SourceMemberContainerTypeSymbol.MakeAllMembers(Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 2217 C#
Symbols.SourceMemberContainerTypeSymbol.GetMembersByNameSlow() Line 1369 C#
Symbols.SourceMemberContainerTypeSymbol.GetMembersByName() Line 1361 C#
Symbols.SourceMemberContainerTypeSymbol.GetMembers(string name) Line 1237 C#
Symbols.SourceMemberContainerTypeSymbol.GetSimpleNonTypeMembers(string name) Line 1252 C#
Symbols.NamedTypeSymbol.GetOperators(string name) Line 216 C#
ConversionsBase.ComputeApplicableUserDefinedImplicitConversionSet(BoundExpression sourceExpression, Symbols.TypeSymbol source, Symbols.TypeSymbol target, Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder d, Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder u, ref System.Collections.Generic.HashSet useSiteDiagnostics, bool allowAnyTarget) Line 245 C#
ConversionsBase.AnalyzeImplicitUserDefinedConversions(BoundExpression sourceExpression, Symbols.TypeSymbol source, Symbols.TypeSymbol target, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 81 C#
ConversionsBase.ClassifyImplicitConversionFromExpression(BoundExpression sourceExpression, Symbols.TypeSymbol destination, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 79 C#
OverloadResolution.CheckArgumentForApplicability(Symbol candidate, BoundExpression argument, Microsoft.CodeAnalysis.RefKind argRefKind, Symbols.TypeSymbol parameterType, Microsoft.CodeAnalysis.RefKind parRefKind, bool ignoreOpenTypes, ref System.Collections.Generic.HashSet useSiteDiagnostics, bool forExtensionMethodThisArg) Line 3415 C#
OverloadResolution.IsApplicable(Symbol candidate, OverloadResolution.EffectiveParameters parameters, AnalyzedArguments arguments, System.Collections.Immutable.ImmutableArray argsToParameters, bool isVararg, bool hasAnyRefOmittedArgument, bool ignoreOpenTypes, bool completeResults, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 3313 C#
OverloadResolution.IsConstructorApplicableInNormalForm(Symbols.MethodSymbol constructor, AnalyzedArguments arguments, bool completeResults, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 545 C#
OverloadResolution.AddConstructorToCandidateSet(Symbols.MethodSymbol constructor, Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder> results, AnalyzedArguments arguments, bool completeResults, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 499 C#
OverloadResolution.ObjectCreationOverloadResolution(System.Collections.Immutable.ImmutableArray constructors, AnalyzedArguments arguments, OverloadResolutionResult result, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 99 C#
Binder.TryPerformConstructorOverloadResolution(Symbols.NamedTypeSymbol typeContainingConstructors, AnalyzedArguments analyzedArguments, string errorName, Microsoft.CodeAnalysis.Location errorLocation, bool suppressResultDiagnostics, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, out MemberResolutionResult memberResolutionResult, out System.Collections.Immutable.ImmutableArray candidateConstructors, bool allowProtectedConstructorsOfBaseType) Line 4918 C#
Binder.BindAttributeConstructor(Syntax.AttributeSyntax node, Symbols.NamedTypeSymbol attributeType, AnalyzedArguments boundConstructorArguments, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, ref LookupResultKind resultKind, bool suppressErrors, ref System.Collections.Generic.HashSet useSiteDiagnostics) Line 495 C#
Binder.BindAttributeCore(Syntax.AttributeSyntax node, Symbols.NamedTypeSymbol attributeType, Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 152 C#
Binder.GetAttribute(Syntax.AttributeSyntax node, Symbols.NamedTypeSymbol boundAttributeType, Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 98 C#
Symbols.SourcePropertySymbol.EarlyDecodeWellKnownAttribute(ref Microsoft.CodeAnalysis.EarlyDecodeWellKnownAttributeArguments arguments) Line 1206 C#
Symbol.EarlyDecodeWellKnownAttributes(System.Collections.Immutable.ImmutableArray binders, System.Collections.Immutable.ImmutableArray boundAttributeTypes, System.Collections.Immutable.ImmutableArray attributesToBind, Symbols.AttributeLocation symbolPart, Symbols.CSharpAttributeData[] boundAttributesBuilder) Line 580 C#
Symbol.LoadAndValidateAttributes(Roslyn.Utilities.OneOrMany> attributesSyntaxLists, ref Microsoft.CodeAnalysis.CustomAttributesBag lazyCustomAttributesBag, Symbols.AttributeLocation symbolPart, bool earlyDecodingOnly, Binder binderOpt, System.Func attributeMatchesOpt) Line 303 C#
Symbols.SourcePropertySymbol.SourcePropertySymbol(Symbols.SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, Syntax.BasePropertyDeclarationSyntax syntax, string name, Microsoft.CodeAnalysis.Location location, Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 94 C#
Symbols.SourcePropertySymbol.Create(Symbols.SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, Syntax.IndexerDeclarationSyntax syntax, Microsoft.CodeAnalysis.DiagnosticBag diagnostics) Line 459 C#
```

Thanks @jcouv

I may sound a bit dump here but from the stack trace, I am not able to map the issue and reasoning. I wonder why it was not able to resolve the basic RuntimeImports symbol because the same symbol has got resolved at say line 166 of StartupCodeHelpers.cs.

It will be very helpful if you can give a heads up on a possible resolution and an expected fix time line.
Looking forward to further communication.

Sorry that was not meant as a resolution, just some notes for further investigation so that I can communicate with team members. The stack trace shows the cycle, which I'll need to find a way to avoid or break.

The way this stack trace reads is we try to prepare information representing the property (ie. construct a property symbol). In order to do that, we check whether the property has any attributes (it does) and we try to understand those attributes (in particular, the IndexerName one). So we need to associate this reference to an attribute (or attribute constructor) to its definition, but this lookup process involves listing the members of the containing type. The problem is that listing those members will try to list (and construct) the property that we were trying to construct at the beginning of this story.

Ahha now i understand it to a level. Thanks a lot for providing the information.
Looking forward to a resolution on this issue.

Was this page helpful?
0 / 5 - 0 ratings