Skip to content

When threads have low free stack space, StackSpiller may infinite-loop through the thread pool #61757

@kouvel

Description

@kouvel

When threads have marginally more than 128 KB of stack space, RuntimeHelpers.TryEnsureSufficientExecutionStack discounts 128 KB of stack space and only considers the remaining space, and there may not be enough even for a non-nested/non-recursive thread pool work item. In that situation, StackGuard.RunOnEmptyStackCore is triggered again from its continuation and keeps doing so since TryEnsureSufficientExecutionStack always returns false.

This appears to be the continuation triggered by RunOnEmptyStackCore, which triggers itself continually:

private Result RewriteExpression(Expression node, Stack stack)
{
if (node == null)
{
return new Result(RewriteAction.None, null);
}
// When compiling deep trees, we run the risk of triggering a terminating StackOverflowException,
// so we use the StackGuard utility here to probe for sufficient stack and continue the work on
// another thread when we run out of stack space.
if (!_guard.TryEnterOnCurrentStack())
{
return _guard.RunOnEmptyStack((StackSpiller @this, Expression n, Stack s) => @this.RewriteExpression(n, s), this, node, stack);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions