D_Parser icon indicating copy to clipboard operation
D_Parser copied to clipboard

Stack overflow in Visual D's D_parser component

Open rainers opened this issue 9 years ago • 6 comments

There have been a number of reports about stack overflow errors in DParserCOMServer, Visual D's D_Parser process, e.g. https://issues.dlang.org/show_bug.cgi?id=15458

I could reproduce the issue in the bug report (not in the debug version, I guess the analyzer timeout kicks in before the stack overflow occurs), but debugging the release build shows that D_Parser is trying to evaluate the return type of object.opEquals.

Here is a snippet of the current definition:

auto opEquals(Object lhs, Object rhs)
{
    // special cases here...
    // General case => symmetric calls to method opEquals
    return lhs.opEquals(rhs) && rhs.opEquals(lhs);
}
auto opEquals(const Object lhs, const Object rhs)
{
    return opEquals(cast()lhs, cast()rhs);
} 

I suspect that return opEquals(cast()lhs, cast()rhs); matches both calls, with the first not considered "better" after casting away const. So the evaluation recurses endlessly.

[Even if the function matching is fixed, I guess there should be a recursion check somewhere.]

rainers avatar Jan 10 '16 23:01 rainers

I can reproduce it now with just this code:

void foo()
{
    Object o;
    o. // invoke completion list after dot => crash
}

rainers avatar Jan 10 '16 23:01 rainers

So it basically wants to

  • resolve opEquals' return type and therefore
  • evaluates the
  • first resturn statements expression, then
  • getting both opEquals-overloads again,
  • whereas the first overload actually might be resolved again - applying the same tuple of arguments

Gotta have a look where to build in the SO check.

aBothe avatar Jan 11 '16 06:01 aBothe

Yes, sounds about right. It seemed to me it is always just spinning on the second overload. It's evaluating the return statement with the casts.

FWIW here's an ever repeating snapshot of the stack:

    D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940   C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.HandleDMethodOverload(D_Parser.Resolver.ResolutionContext ctxt, bool eval, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, bool returnBaseTypeOnly, System.Collections.Generic.List<D_Parser.Resolver.AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, D_Parser.Resolver.MemberSymbol ms, ref D_Parser.Resolver.AbstractType untemplatedMethod) Line 365    C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.EvalMethodCall(D_Parser.Resolver.AbstractType[] baseExpression, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, D_Parser.Dom.Expressions.TemplateInstanceExpression tix, D_Parser.Resolver.ResolutionContext ctxt, D_Parser.Dom.Expressions.PostfixExpression_MethodCall call, out System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, out D_Parser.Resolver.ExpressionSemantics.ISymbolValue delegateValue, bool returnBaseTypeOnly, D_Parser.Resolver.ExpressionSemantics.AbstractSymbolValueProvider ValueProvider) Line 229 C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.Visit(D_Parser.Dom.Expressions.PostfixExpression_MethodCall call) Line 109  C#
    D_Parser.dll!D_Parser.Dom.Expressions.PostfixExpression_MethodCall.Accept<D_Parser.Resolver.AbstractType>(D_Parser.Dom.ExpressionVisitor<D_Parser.Resolver.AbstractType> vis) Line 65   C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.EvaluateType(D_Parser.Dom.Expressions.IExpression x, D_Parser.Resolver.ResolutionContext ctxt, bool tryReturnMethodReturnType) Line 85  C#
    D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940   C#

rainers avatar Jan 11 '16 07:01 rainers

Yep, this is the repeating pattern I get in stack overflow crashes:

    D_Parser.dll!D_Parser.Dom.Expressions.PostfixExpression_MethodCall.Accept<D_Parser.Resolver.AbstractType>(D_Parser.Dom.ExpressionVisitor<D_Parser.Resolver.AbstractType> vis) Line 65 + 0x1d bytes  C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.EvaluateType(D_Parser.Dom.Expressions.IExpression x, D_Parser.Resolver.ResolutionContext ctxt, bool tryReturnMethodReturnType) Line 85 + 0x5b bytes C#
    D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940 + 0x16 bytes  C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.HandleDMethodOverload(D_Parser.Resolver.ResolutionContext ctxt, bool eval, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, bool returnBaseTypeOnly, System.Collections.Generic.List<D_Parser.Resolver.AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, D_Parser.Resolver.MemberSymbol ms, ref D_Parser.Resolver.AbstractType untemplatedMethod) Line 365 + 0xa bytes    C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.EvalMethodCall(D_Parser.Resolver.AbstractType[] baseExpression, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, D_Parser.Dom.Expressions.TemplateInstanceExpression tix, D_Parser.Resolver.ResolutionContext ctxt, D_Parser.Dom.Expressions.PostfixExpression_MethodCall call, out System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, out D_Parser.Resolver.ExpressionSemantics.ISymbolValue delegateValue, bool returnBaseTypeOnly, D_Parser.Resolver.ExpressionSemantics.AbstractSymbolValueProvider ValueProvider) Line 229 + 0x3b bytes    C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.Visit(D_Parser.Dom.Expressions.PostfixExpression_MethodCall call) Line 109 + 0x6e bytes C#
    D_Parser.dll!D_Parser.Dom.Expressions.PostfixExpression_MethodCall.Accept<D_Parser.Resolver.AbstractType>(D_Parser.Dom.ExpressionVisitor<D_Parser.Resolver.AbstractType> vis) Line 65 + 0x1d bytes  C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.EvaluateType(D_Parser.Dom.Expressions.IExpression x, D_Parser.Resolver.ResolutionContext ctxt, bool tryReturnMethodReturnType) Line 85 + 0x5b bytes C#
    D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940 + 0x16 bytes  C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.HandleDMethodOverload(D_Parser.Resolver.ResolutionContext ctxt, bool eval, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, bool returnBaseTypeOnly, System.Collections.Generic.List<D_Parser.Resolver.AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, D_Parser.Resolver.MemberSymbol ms, ref D_Parser.Resolver.AbstractType untemplatedMethod) Line 365 + 0xa bytes    C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.EvalMethodCall(D_Parser.Resolver.AbstractType[] baseExpression, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, D_Parser.Dom.Expressions.TemplateInstanceExpression tix, D_Parser.Resolver.ResolutionContext ctxt, D_Parser.Dom.Expressions.PostfixExpression_MethodCall call, out System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, out D_Parser.Resolver.ExpressionSemantics.ISymbolValue delegateValue, bool returnBaseTypeOnly, D_Parser.Resolver.ExpressionSemantics.AbstractSymbolValueProvider ValueProvider) Line 229 + 0x3b bytes    C#
    D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.Visit(D_Parser.Dom.Expressions.PostfixExpression_MethodCall call) Line 109 + 0x6e bytes C#

thedeemon avatar Jan 11 '16 23:01 thedeemon

@rainers The SO part should be resolved now. Still, it does not compare method parameter types atm.

aBothe avatar Jan 12 '16 11:01 aBothe

@aBothe Thanks. Works fine now. I had to change the line https://github.com/aBothe/D_Parser/commit/56c57a7df31ca0965ccfe674fdb430d3ad134b65#diff-cac2168692965ba74c9fbdb7b584bdfdR153 as I'm still compiling with VS2013 (.? is not supported).

rainers avatar Jan 13 '16 21:01 rainers