Skip to content

Avoid OOM in Task.AddExceptionsForCompletedTask during stress runs (#136268) - #136751

Open
omid-io wants to merge 3 commits into
dotnet:mainfrom
omid-io:fix/task-addexceptions-oom
Open

omid-io wants to merge 3 commits into
dotnet:mainfrom
omid-io:fix/task-addexceptions-oom

Conversation

@omid-io

@omid-io omid-io commented Oct 31, 2026

Copy link
Copy Markdown

Description

Fixes #136268.

In Windows x86 CoreCLR CI runs, System.Threading.Tasks.Tests.TaskContinueWithTests.RunContinueWithStressTestsNoState was failing with System.OutOfMemoryException inside StringBuilder.ToString().

Root Cause

When waiting on a large number of tasks (e.g., 5,000–10,000+ canceled continuation tasks in stress tests), Task.WaitAllCore iterates over all tasks and calls Task.AddExceptionsForCompletedTask(ref exceptions, task).
Previously, this routed through ask.GetExceptions(true), which for each canceled task:

  1. Created a new TaskCanceledException.
  2. Called canceledException.SetCurrentStackTrace(), walking the call stack with
    ew StackTrace(fNeedFileInfo: true) and serializing the trace via StringBuilder allocations.
  3. Wrapped it into an intermediate AggregateException, solely for AddExceptionsForCompletedTask to immediately extract ex.InternalInnerExceptions and discard the wrapper.

Under 32-bit x86 address space constraints (2GB user space), generating thousands of stack trace captures and strings concurrently caused address space exhaustion and OutOfMemoryException.

Fix

In Task.AddExceptionsForCompletedTask:

  • If .ExceptionRecorded is true, continue retrieving exceptions via .GetExceptions(true) and copy them to the list.
  • If .IsCanceled (with no other exceptions recorded), directly add
    ew TaskCanceledException(t) to the exception list without triggering expensive stack trace formatting or intermediate AggregateException allocations.
  • Preserve .UpdateExceptionObservedStatus() to ensure attached child semantics remain intact.

…ionsForCompletedTask (dotnet#136268)

Signed-off-by: Omid Zaferi <omidzaferi@gmail.com>
@github-actions github-actions Bot added the area-ExceptionHandling-coreclr only use for closed issues label Oct 31, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Oct 31, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The change loses diagnostic stack traces on inner TaskCanceledException instances from WaitAll, requiring trace preservation and a regression assertion for their StackTrace.

1 open issue
What changed in this PR

This PR targets the Windows x86 stress-test OOM reported in #136268 by reducing canceled-task exception allocations in CoreLib’s Task.WaitAll path.

Changes:

  • Adds canceled-task exceptions directly, avoiding per-task stack-trace capture and intermediate AggregateException allocations.
  • Retains existing exception retrieval for recorded faults and preserves exception-observation bookkeeping.
File Description
src/​libraries/​System.Private.CoreLib/​src/​System/​Threading/​Tasks/​Task.cs Adds a cancellation-specific path in AddExceptionsForCompletedTask to reduce allocations.

Review effort: Balanced

…ithout per-task capture OOM (dotnet#136268)

Address review feedback by jkotas and Copilot: capture synthetic stack trace once per WaitAll invocation and share it across TaskCanceledException instances, eliminating OOM while preserving diagnostic stack traces and back-compat.
@jkotas jkotas added area-System.Threading.Tasks and removed area-ExceptionHandling-coreclr only use for closed issues labels Nov 1, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-threading-tasks
See info in area-owners.md if you want to be subscribed.

This branch has not been deployed

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

Labels

area-System.Threading.Tasks community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ci-scan] Test failure: System.Threading.Tasks.Tests.TaskContinueWithTests.RunContinueWithStressTestsNoState

3 participants