Skip to content

Add regression test for ValueTuple StackOverflow in large Dictionary initializers#121120

Merged
jkotas merged 8 commits intomainfrom
copilot/fix-stackoverflow-valuetuple
Oct 28, 2025
Merged

Add regression test for ValueTuple StackOverflow in large Dictionary initializers#121120
jkotas merged 8 commits intomainfrom
copilot/fix-stackoverflow-valuetuple

Conversation

Copy link
Contributor

Copilot AI commented Oct 27, 2025

Regression test for ValueTuple Dictionary StackOverflow issue

The test verifies that large Dictionary collection initializers with ValueTuple values don't cause StackOverflowException. The issue was caused by excessive JIT-created temporary structs on the stack. With 5000 entries, this test validates the JIT optimizations that were implemented to fix this issue.

The test only verifies the dictionary count to avoid floating-point equality issues, as the primary purpose is to ensure the code doesn't overflow the stack during compilation/execution.

Original prompt

This section details on the original issue you should resolve

<issue_title>System.ValueTuple causes a StackOverflow when used in a large Dictionary.</issue_title>
<issue_description>Moved (and edited) this issue from the roslyn repo.

Summary: you add an empty Main method to the attached code, then compile it with csc.exe geocoords_stackoverflow.cs.txt. When you run the resulting executable, you get an overflow error (Process is terminated due to StackOverflowException.)

From discussion with @VSadov, we think this is a JIT issue rather than a compiler issue.
FYI @jkotas for triage. Thanks


@andras-ferencz commented on Tue Feb 28 2017

When using the new System.ValueTuple in a large Dictionary, I receive a stack overflow exception where as I do not with System.Tuple.

Dictionary<int, (double lat, double lon)> zipcodes = new Dictionary<int, (double lat, double lon)>() {{123,(18.180555,-66.749961)} }; works fine just for reference.

geocoords_stackoverflow.cs.txt
geocoords_worksfine.cs.txt


@jcouv commented on Tue Feb 28 2017

I'm able to see the repro file. The code causing stack overflow looks like this:

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Net.Mail;

namespace HAL
{
    public static partial class geo
    {
        public static Dictionary<int,(double lat, double lon)> zipcodes = new Dictionary<int, (double lat, double lon)>()
{{00601,(18.180555,-66.749961)},
{00602,(18.361945,-67.175597)},
{00603,(18.455183,-67.119887)},
{00606,(18.158345,-66.932911)},
{00610,(18.295366,-67.125135)},
{00612,(18.402253,-66.711397)},
{00616,(18.420412,-66.671979)},
{00617,(18.445147,-66.559696)},
{00622,(17.991245,-67.153993)},
{00623,(18.083361,-67.153897)},
{00624,(18.064919,-66.716683)},
{00627,(18.412600,-66.863926)},
{00631,(18.190607,-66.832041)},
... goes on and on...
{99922,(55.307528,-133.046815)},
{99923,(56.002315,-130.041026)},
{99925,(55.550204,-132.945933)},
{99926,(55.138352,-131.470424)},
{99927,(56.239062,-133.457924)},
{99929,(56.370751,-131.693301)}}; // total is about 33100 lines

    }
}

@jcouv commented on Wed Sep 20 2017

I'm able to repro this. The program compiles fine, but it overflows when run.

The strange thing is that decompiling the static constructor shows that it only expects to use very little IL stack (.maxstack 4 from debug compilation):

.method private hidebysig specialname rtspecialname static 
        void  .cctor() cil managed
{
  // Code size       1160053 (0x11b375)
  .maxstack  4
  .locals init (class [mscorlib]System.Collections.Generic.Dictionary`2<int32,valuetype [mscorlib]System.ValueTuple`2<float64,float64>> V_0)
  IL_0000:  newobj     instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,valuetype [mscorlib]System.ValueTuple`2<float64,float64>>::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  ldc.i4     0x259
  IL_000c:  ldc.r8     18.180554999999998
  IL_0015:  ldc.r8     -66.749960999999999
  IL_001e:  newobj     instance void valuetype [mscorlib]System.ValueTuple`2<float64,float64>::.ctor(!0,
                                                                                                     !1)
  IL_0023:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,valuetype [mscorlib]System.ValueTuple`2<float64,float64>>::Add(!0,
                                                                                                                                                                  !1)
  IL_0028:  nop
  IL_0029:  ldloc.0
  IL_002a:  ldc.i4     0x25a
  IL_002f:  ldc.r8     18.361944999999999
  IL_0038:  ldc.r8     -67.175596999999996
  IL_0041:  newobj     instance void valuetype [mscorlib]System.ValueTuple`2<float64,float64>::.ctor(!0,
                                                                                                     !1)
  IL_0046:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,valuetype [mscorlib]System.ValueTuple`2<float64,float64>>::Add(!0,
                                                                                                                                                                  !1)
  IL_004b:  nop
  IL_004c:  ldloc.0
  IL_004d:  ldc.i4     0x25b
  IL_0052:  ldc.r8     18.455183000000002
  IL_005b:  ldc.r8     -67.119887000000006
  IL_0064:  newobj     instance void valuetype [mscorlib]System.ValueTuple`2<float64,float64>::.ctor(!0...

</details>

- Fixes dotnet/runtime#8980

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

…tHub #17455)

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix stack overflow issue with System.ValueTuple in Dictionary Add regression test for ValueTuple StackOverflow in large Dictionary initializers Oct 27, 2025
Copilot AI requested a review from stephentoub October 27, 2025 16:50
@stephentoub
Copy link
Member

@copilot, this addresses #8980 not dotnet/roslyn#17455 (the latter was already closed)

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 27, 2025

@copilot, this addresses #8980 not dotnet/roslyn#17455 (the latter was already closed)

Updated in commit 732bca3. Renamed test from GitHub_17455 to Runtime_8980 and changed issue reference to #8980.

@stephentoub stephentoub added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Oct 27, 2025
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@jkotas
Copy link
Member

jkotas commented Oct 27, 2025

@copilot The test should not be catching exceptions. Instead, it should leave the exception unhandled. It provides better diagnostic experience.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 27, 2025

@copilot The test should not be catching exceptions. Instead, it should leave the exception unhandled. It provides better diagnostic experience.

Fixed in commit e00168c. Removed try-catch block so exceptions propagate naturally for better diagnostics.

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
@stephentoub stephentoub marked this pull request as ready for review October 27, 2025 19:30
Copilot AI review requested due to automatic review settings October 27, 2025 19:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds a regression test for a JIT stack overflow issue that occurred when using large Dictionary initializers with ValueTuple values. The test validates that the JIT can properly handle dictionary initialization with 5000 ValueTuple entries without causing a StackOverflowException.

Key changes:

  • Added new regression test Runtime_8980 with large Dictionary initializer containing 5000 ValueTuple entries
  • Configured project to disable XUnit wrapper generator to prevent source generation stack overflow

@jkotas
Copy link
Member

jkotas commented Oct 27, 2025

/azp run runtime-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member

jkotas commented Oct 27, 2025

/azp run runtime-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member

jkotas commented Oct 28, 2025

/azp run runtime-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member

jkotas commented Oct 28, 2025

/ba-g infrastructure timeouts

@jkotas jkotas merged commit 25800e6 into main Oct 28, 2025
121 of 127 checks passed
@jkotas jkotas deleted the copilot/fix-stackoverflow-valuetuple branch October 28, 2025 22:01
jkotas pushed a commit that referenced this pull request Oct 30, 2025
Fix test build with `BuildAllTestsAsStandalone`, regression after
#121120

Fixed similar to
`src/tests/JIT/Regression/JitBlue/GitHub_10215/GitHub_10215.cs`
@github-actions github-actions bot locked and limited conversation to collaborators Nov 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants