Repository navigation
Test Failure: System.Text.RegularExpressions.Tests #128330
Description
Activity
- addedarea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
on May 18, 2026 dotnet-policy-service commented
on May 18, 2026 ContributorMore actionsTagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.@kotlarmilos, forwarding to you to check why this issue can be missed by the ci-scan.
cc @janvorli. Is this GC area issue?
- marked Test Failure: System.Text.Encoding.Tests #128046 as a duplicate of this issue
on May 21, 2026 - addedblocking-clean-ci-optionalBlocking optional rolling runsBlocking optional rolling runs
on May 21, 2026 Failed in (1):
Console Log: Console Log
Source: runtime-coreclr libraries-jitstress2-jitstressregs / net11.0-windows-Release-x86-jitstress2_jitstressregs3-Windows.10.Amd64.Open / System.Text.RegularExpressions.TestsGenerated by ci-pipeline-monitor/scripts/update_github.py
Dump Analysis
Dump:
dotnet.exe.55140.dmp(Windows x86, 32-bit) from Helix job90cffbd1-cae8-4b84-bab1-cd2e6df06092, work itemSystem.Text.RegularExpressions.Tests, build 1423181.Note: SOS cannot load for x86 target from x64 debugger, so analysis was done with native CDB commands only.
Crash Details
Assert:
MethodTable::SanityCheck()atmethodtable.cpp:8697Full call chain (from assert message):
Object::ValidateInner → Object::Validate → WKS::GCHeap::Relocate → GcEnumObject → EnumGcRefsX86 → EECodeManager::EnumGcRefs → GcStackCrawlCallBack → Thread::StackWalkFramesEx → ScanStackRootsWhat Happened
GC thread 24 (0x5210) triggered a GC and is scanning thread 16 (0x4a40)'s stack. The x86 GC enumerator (
EnumGcRefsX86) is walking the frame of an async state machineMoveNextmethod (Roslyn'sConvertFieldToGeneratedRegexProperty.MoveNext()) at method start0x28c36138, curOffs0x23f.At curOffs
0x23f, the code is:28c36371: call [25927960h] ; SemanticModel.GetOperation (virtual dispatch) 28c36377: lea edx, [edi+1Ch] ; ← curOffs 0x23f = IP after call return 28c3637a: call RhpCheckedAssignRefEAXAVLocation ; write barrier store of eax into [edi+1Ch]
The GC info at this offset reports stack slot
[0x5449ef64]as containing a GC object reference. But the actual value is:Address Value What it is 0x5449ef640x5449f184Stack address — points within the same thread's stack 0x5449f1840x298f7630A heap object (valid, but this is the pointee, not what GC sees) The slot contains a byref/interior pointer to a stack location, not an object reference. When the GC's
Relocatephase tries to validate0x5449f184as an object (callingMethodTable::SanityCheck), it fails because it's a stack address, not a heap object.Root Cause
x86 JIT GC encoding bug under
jitstressregs3: The JIT32 GC encoder (EnumGcRefsX86) incorrectly reports abyref(interior pointer) stack slot as a regularref(object reference) slot.Under
jitstressregs3, the extreme register pressure on x86's 6 general-purpose registers forces the JIT to spill locals that would normally be enregistered. The async state machineMoveNextmethod has bothref(object reference) andbyref(interior/stack pointer) locals. When the stress mode forces these into different stack slots than normal, the GC encoder's tracking ofrefvsbyreftype for spilled locals gets confused, encoding abyrefslot asref.Evidence:
- Stack at
0x5449ef48contains0x12345678— the JIT's poison fill pattern for uninitialized debug locals, confirming this is a Checked/debug JIT build with stress - The method is an async
MoveNextwith many locals (frame size0x1C4= 452 bytes) - The bad slot is deep in the frame, likely a compiler-generated temp for a
ref structorSpan<T>byref
Why x86-Specific
- x86 uses
JIT32_GCENCODER— a completely different GC encoding format from x64'sGcInfoEncoder. The x86 encoder usesregPtrDsclinked lists and different slot tracking. - x86 has only 6 GP registers (eax, ecx, edx, ebx, esi, edi) —
jitstressregs3on x86 creates much more extreme spill pressure than on x64 with 14 GP registers. - The x86 GC encoder's handling of
byrefvsreffor spilled locals under stress may have a bug that doesn't exist in the newer x64GcInfoEncoder.
Recommended Next Steps
- Reproduce: Run Roslyn's
ConvertFieldToGeneratedRegexPropertyunderDOTNET_JitStress=2 DOTNET_JitStressRegs=3on x86 Checked build - JIT investigation: Check
gcencode.cpp'sgcMakeRegPtrTablefor the JIT32 encoder path — specifically howbyrefvsreftype is tracked for spilled temporaries in asyncMoveNextmethods - JitDump: Get JIT dump for the
MoveNextmethod withDOTNET_JitDump=*ConvertFieldToGeneratedRegexProperty*under the same stress to see the GC encoding decisions
- Stack at
Not sure that reasoning makes much sense (
MoveNextis not a runtime async method), but I'll take a look regardless.Logs are gone and I don't see similar failures in recent runs. Don't think this is actionable now. I will look at some of the more recent failures.
- locked and limited conversation to collaborators
on Aug 9, 2026

Summary:
CLR "SanityCheck()" assertion at methodtable.cpp:8697 fires during garbage collection stack walk (Object::Validate -> WKS::GCHeap::Relocate -> ScanStackRoots), causing FailFast and process termination on windows-x86 under jitstress2_jitstressregs3. The test (System.Text.RegularExpressions.Tests) appears incidental — the failing assertion is in the GC scan, not in the regex code.
Failed in (1):
Console Log: Console Log
Source: runtime-coreclr libraries-jitstress2-jitstressregs / net11.0-windows-Release-x86-jitstress2_jitstressregs3-Windows.10.Amd64.Open / System.Text.RegularExpressions.Tests
Failed tests:
Error Message:
Stack Trace:
Analysis:
No matching open or closed GitHub issue found via search passes for: "RegularExpressions.Tests jitstress", "jitstress2_jitstressregs3 SanityCheck", "Object Validate FailFastOnAssert jitstress2 x86", "Regression SanityCheck methodtable.cpp 8697". This appears to be a NEW failure. Worth filing — likely a JIT codegen bug on x86 under jitstress2_jitstressregs3 that produces an object reference the GC stack walker cannot validate.
Generated by ci-pipeline-monitor/scripts/update_github.py