Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for #89645, stack overflow in Crossgen2 #90229

Merged
merged 1 commit into from
Aug 11, 2023

Conversation

trylek
Copy link
Member

@trylek trylek commented Aug 9, 2023

After David Wrighton's refactoring of type loadability check in #89415 we started seeing stack overflow in Crossgen2 compilation of the outerloop test

Loader/classloader/generics/regressions/DD117522/Test.csproj

This is because the test is a negative test that exercises runtime behavior in the presence of a non-loadable type with recursive definition. David's stricter descent into the type ends up in an infinite recursion when presented with this invalid type.

I haven't found any easy way to incorporate the additional check for recursive types into the loadability algorithm - in fact I'm not even sure whether that's generally doable.

As a very simple way to protect against the infinite recursion I propose adding a heuristic limit for the type analysis stack size. I assume the proposed value 1024 to be more than enough for both Crossgen2 and NativeAOT, if it's realistic that NativeAOT can encounter deeper types than this, I can make the check specific for Crossgen2.

Thanks

Tomas

Fixes: #89645

/cc @dotnet/crossgen-contrib

After David Wrighton's refactoring of type loadability check
in dotnet#89415 we started seeing stack overflow in Crossgen2 compilation
of the outerloop test

Loader/classloader/generics/regressions/DD117522/Test.csproj

This is because the test is a negative test that exercises runtime
behavior in the presence of a non-loadable type with recursive
definition. David's stricter descent into the type ends up in an
infinite recursion when presented with this invalid type.

I haven't found any easy way to incorporate the additional check
for recursive types into the loadability algorithm - in fact I'm
not even sure whether that's generally doable.

As a very simple way to protect against the infinite recursion
I propose adding a heuristic limit for the type analysis stack
size. I assume the proposed value 1024 to be more than enough for
both Crossgen2 and NativeAOT, if it's realistic that NativeAOT can
encounter deeper types than this, I can make the check specific
for Crossgen2.

Thanks

Tomas

Fixes: dotnet#89645
@jkotas
Copy link
Member

jkotas commented Aug 10, 2023

in fact I'm not even sure whether that's generally doable.

It is doable. The algorithm is described in ECMA spec and implemented in CoreCLR by this call:

if (locals.newVisited.CheckForIllegalRecursion())

@jkotas
Copy link
Member

jkotas commented Aug 10, 2023

1024 to be more than enough for both Crossgen2 and NativeAOT

It is likely still going to crash on macOS since the default stacktrace on macOS is much smaller currently. (We have a few other places running into this problem - tracked by #87879.)

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

I assume the proposed value 1024 to be more than enough for both Crossgen2 and NativeAOT

I agree. This limit looks liberal enough to be hardcoded.

@jkotas jkotas merged commit dac2202 into dotnet:main Aug 11, 2023
106 checks passed
@trylek trylek deleted the Crossgen2StackOverflowFix branch September 5, 2023 19:29
@ghost ghost locked as resolved and limited conversation to collaborators Oct 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants