Repository navigation
Description
Build Information
Build: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1582146
Build error leg or test failing: coreclr Pri0 Runtime Tests Run R2R_CG2 browser wasm checked — Regression_1 work item
Pull request: #133210
The Regression_1 work item in the browser-wasm ReadyToRun runtime-test leg asserts in Frame::Pop with frame-chain corruption. Helix job f484f658-1090-4625-adf3-8f35293caf50.
This is a different shape from #133219 (Object::Validate, GC-mode) and from the now-fixed #133220 (Thread::ObjectRefFlush). It is a frame-chain ordering assert, not a GC-mode assert, so it needs its own match block — Build Analysis matches on error text.
Helix categorises this as InfrastructureError. It is not — it is a real product assert in a checked runtime.
Error Details
at EHTest.f1(Int64 arg0, Int64 arg1, Int64 arg2, Int32 arg3, Int64 arg4)
01:14:07.505 Failed test: JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b125091/b125091/b125091.dll
ASSERT FAILED
Expression: pThread->GetFrame() == this && "Popping a frame out of order ?"
Location: /__w/1/s/src/coreclr/vm/frames.cpp:609
Function: Pop
Process: 42
Frame (PrestubMethodFrame): 0x4fef1c
Skipping 0x4fef1c
The failing test is JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b125091, an exception-handling test. The assert fires immediately after a System.AppDomainUnloadedException surfaces from EHTest.f1.
Context
Every remaining failure in this leg is an exception-handling test reaching an R2R delay-load pinvoke — b125091 here, NonVoidThrowHelper in JIT.opt (#133219), throwinfinally_50 in Methodical_d1, CctorThrowInlinedStatic in Loader. That is a better characterisation of the residue than the generic-dictionary-lookup theory in #132022, which #132420 already addressed.
Lead, not a fix
PopExplicitFrames (src/coreclr/vm/exceptionhandling.cpp:481-510) decides whether to pop or merely Reset() an active InlinedCallFrame when an exception unwinds through an inline pinvoke. It tests ExecutionManager::IsReadyToRunCode(m_pCallerReturnAddress), but wasm has no return address — JIT_PInvokeBeginImpl (src/coreclr/vm/wasm/helpers.cpp:708) stores the sentinel INLINED_PINVOKE_FROM_R2R (== 1, frames.h:792). IsReadyToRunCode((PCODE)1) finds no RangeSection and returns false, so the frame is Reset() but left linked on the thread frame chain. stackwalk.cpp:2335 already special-cases this exact sentinel under #ifdef TARGET_WASM; PopExplicitFrames has no equivalent. USE_PER_FRAME_PINVOKE_INIT is TARGET_64BIT-only, so wasm32 takes that branch.
That is a plausible cause of this assert specifically. It has not been validated against this test — a prototype was built and tested against JIT.opt/#133219, where it changed nothing, and was reverted rather than shipped unverified. Recording it so the next person does not have to re-derive it.
Error Message
{
"ErrorMessage": [
"Expression: pThread->GetFrame() == this && \"Popping a frame out of order ?\"",
"Location: /__w/1/s/src/coreclr/vm/frames.cpp:609",
"Function: Pop",
"Process: 42"
],
"ErrorPattern": "",
"BuildRetry": false,
"ExcludeConsoleLog": false
}Why the match block is scoped this way
Array form: each element matches one line, in order, with arbitrary lines allowed between them.
"Popping a frame out of order ?" on its own is platform-neutral and would match this assert anywhere, on any architecture. The four elements together scope it: exact assert text, exact source location, asserting function, and Process: 42 — emscripten's fixed PID, which native platforms do not report. That last element keeps the match on browser-wasm.
All four elements were verified verbatim against the Regression_1 console log for Helix job f484f658-1090-4625-adf3-8f35293caf50.
Match-block verification
Every element was checked verbatim against the failing Helix console log for the job cited above.
The element set (Expression: / Location: / Function: / Process:) mirrors the block in #131925, which matched this same assert 277 times in a month — evidence that these lines are present in the artifact Build Analysis matches against. #131925 stopped matching because its block additionally pins object.cpp:514 (this build reports :506) and text specific to Loader/ContextualReflection, whose test has since been disabled on browser-wasm.
Outstanding: I have not yet observed a Build Analysis run attribute an occurrence to this issue, so the match is reasoned rather than demonstrated. If it does not pick up, the likely cause is that these merged-runner work items abort without publishing a test result for Build Analysis to attach to, in which case the fallback is a test-disable change rather than a KBE.
Note
This issue was authored with GitHub Copilot.
Known issue validation
Build: 🔎 https://dev.azure.com/dnceng-public/public/_build/results?buildId=1582146
Error message validated: [Expression: pThread->GetFrame() == this && "Popping a frame out of order ?" Location: /__w/1/s/src/coreclr/vm/frames.cpp:609 Function: Pop Process: 42]
Result validation: ❌ Known issue did not match with the provided build.
Validation performed at: 9/4/2026 3:40:40 AM UTC
Report
| Build | Repository | Test | Pull Request |
|---|---|---|---|
| 1659118 | dotnet/runtime | OutOfProcessTest.Loader/binding/tracing/BinderTracingTest.ResolutionFlow/BinderTracingTest.ResolutionFlow.cmd | #136163 |
Summary
| 24-Hour Hit Count | 7-Day Hit Count | 1-Month Count |
|---|---|---|
| 0 | 0 | 1 |
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
dotnet-policy-service commentedon Sep 4, 2026
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.
dotnet-policy-service commentedon Sep 4, 2026
Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.
lewing commentedon Sep 4, 2026
Status of the
PopExplicitFrameslead recorded in the description — it is now better characterised, and it is the best remaining candidate for this issue specifically, but it is still untested againstb125091.Verified twice by independent inspection: on wasm the predicate in
PopExplicitFrames(exceptionhandling.cpp:481-510) is always false.ExecutionManager::IsReadyToRunCode(m_pCallerReturnAddress)is called with theINLINED_PINVOKE_FROM_R2Rsentinel (== 1,frames.h:792) thatJIT_PInvokeBeginImplstores because wasm has no return address, and no RangeSection covers(PCODE)1. So the R2RInlinedCallFrameunlink is dead code on wasm, and the frame isReset()but left linked on the thread frame chain — which is exactly the precondition forFrame::Popasserting that it is popping out of order.Ruled out for #133219, not for this issue. During a
JIT.optrepro of that other shape there were 25,854 entries toPopExplicitFrameswith 0 active-InlinedCallFramehits, and building the one-line fix left that assert unchanged. That is evidence it is not the cause there; it says nothing about here, becauseb125091is an exception-handling test and this assert is a frame-chain ordering violation.Not yet tested against
b125091— theJIT/Regressionsubtree was not built in time. Next step for whoever picks this up: build that subtree, reproduce this assert, then apply the sentinel check toPopExplicitFramesmirroring the existing#ifdef TARGET_WASMspecial case atstackwalk.cpp:2335, and see whether it clears.USE_PER_FRAME_PINVOKE_INITisTARGET_64BIT-only, so wasm32 definitely takes the affected branch.Also note the QCall-transition theory from #132022 has now been empirically refuted for the
object.cpp:506shape (details in #133219). It was never tested for this shape, so treat it as unknown here rather than inherited.Note
This comment was authored with GitHub Copilot.
Narrow browser WASM R2R test exclusions (#133310)
jeffschwMSFT commentedon Oct 12, 2026
removing blocking-clean-ci as it has not failed in 30 days
lewing commentedon Oct 27, 2026
Reproducibility analysis for this assert. I could not reproduce it, and I did not identify a cause or a fix.
What failed: Build 1582146 ran the
R2R_CG2 browser wasm checkedleg on PR #133210's final head,f110d3585f(base25f20c2fd36). That head already contains the long-local narrowing fix, so #133210 itself is not the fix. This is the only recorded occurrence I found. The R2R leg does not appear in the check runs of the PR's six earlier pushes, and a search of dotnet/runtime for the assert text finds only this issue (plus #133219, a different GC-mode assert, and an unrelated 2019 report).Local attempts (macOS arm64, browser-wasm Checked CoreCLR, libraries Release, Crossgen2 layout,
RunCrossGen2=1, fullJIT/Regression/Regression_1wrapper, 107 tests passed in every run, no asserts,b125091passed each time):f110d3585f7e807becb8c(+ a local GC-mode patch)7e807becb8cwith #133136 (SCC dispatcher fix) reverted14d606fc70aIsManagedCodefor wasm virtual IPs) revertedReading of the log: the dump shows a single
PrestubMethodFrameas the top frame, soFrame::Popwas called on a frame that is not on the chain. That fits a frame-chain bookkeeping problem. ThePopExplicitFramessentinel lead from the description is still untested against this assert.Not tested: other fixes that landed after the failing build and touch the same area were not isolated: #132965 (hand-written R2R-to-interpreter thunks removed), #133111 (framework R2R through the SDK pipeline), #133922 (prestub frame lifecycle). The CI build, logs and Helix job have expired, so I could not compare the Helix environment with my local one.
Since then: the issue's hit counts are 0/0/0, but Build Analysis never matched this issue, so that is weak evidence. #133310 reports
b125091passing in the exact-base R2R baseline (#133308). #133305 and #133463 report it unsuppressed and passing in builds 1588226, 1588519 and 1589007, after #133463 restored the lane as non-blocking. I did not check results after mid-September.It looks like a one-off or an already-fixed failure rather than an open product bug, but I cannot prove either. Leaving the issue open for now. If someone wants to close it, a clean run of the R2R lane would back that up.
Note
This comment was drafted with GitHub Copilot.