You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When producing the browser-wasm framework ReadyToRun images, crossgen2 crashes while compiling System.Linq.Parallel. The failing method is the shared-generic instantiation:
(and the same for Pair<int64,int64>), which come from System.Linq.Parallel.
The Exec of crossgen2 exits with -532462766 (0xE0434352, unhandled managed exception), reported as MSB3073 from Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj (_CrossgenBrowserFrameworkR2R).
Exception
Unhandled exception. ILCompiler.CodeGenerationFailedException: Code generation failed for method
'[S.P.CoreLib]System.GC.<AllocateUninitializedArray>g__AllocateNewArrayWorker|77_0<Pair`2<float64,int64>>(int32,bool)'
---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at Internal.JitInterface.CorInfoImpl.HandleToObject(Void* handle) in CorInfoImpl.cs:line 767
at Internal.JitInterface.CorInfoImpl.getMethodNameFromMetadata(...) in CorInfoImpl.cs:line 3920
--- End of inner exception stack trace ---
at Internal.JitInterface.CorInfoImpl.CompileMethodInternal(...) in CorInfoImpl.cs:line 375
at ILCompiler.ReadyToRunCodegenCompilation...CompileOneMethod(...)
Steps to reproduce
Build the browser-wasm CoreCLR runtime pack (Release), which runs the framework R2R crossgen step:
The crash is in the JIT importer, not the wasm codegen backend. Compiler::lookupNamedIntrinsic (src/coreclr/jit/importercalls.cpp) is invoked with a null method handle (CORINFO_METHOD_HANDLE/gtCallMethHnd == NO_METHOD_HANDLE, e.g. an indirect call). It passes that handle straight to info.compCompHnd->getMethodNameFromMetadata(method, ...); on the crossgen2 side that does HandleToObject(ftn) → _handleToObject[index] with index = ((int)ftn - handleBase) / handleMultiplier. For ftn == 0 this is a large negative index → ArgumentOutOfRangeException.
Instrumenting crossgen2's getMethodNameFromMetadata confirmed the handle value:
AGENT_DEBUG getMethodNameFromMetadata bad ftn=0x0 odd=0 idx=-540672 count=3866
Returning early from that callback then surfaced a second, identical trap on the same null handle at the lookupNamedIntrinsic fallback info.compCompHnd->getArrayIntrinsicID(method) (CorInfoImpl.csgetArrayIntrinsicID), proving the bad caller is lookupNamedIntrinsic itself.
lookupNamedIntrinsic has ~30 call sites, several of which pass call->gtCallMethHnd on arbitrary calls (including indirect calls with NO_METHOD_HANDLE, and helper calls whose handle is the odd-encoded eeFindHelper value). The wasm framework bubble compiles the shared-generic value-type instantiation AllocateUninitializedArray<Pair<double,long>> (--opt-cross-module:*) where the typeof(T[]) / array-handling tree reaches one of these sites with a null handle. The bug is latent on other targets that don't compile this exact tree shape.
Fix (validated)
Guard lookupNamedIntrinsic to return NI_Illegal for a null or helper handle (neither is ever a named intrinsic), which protects every call site:
Validated: with this guard in the rebuilt clrjit_universal_wasm_x64, crossgen2 compiles System.Linq.Parallel.wasm successfully (R2R image emitted, exit 0) instead of crashing.
Note
This issue text was generated with the assistance of GitHub Copilot.
Description
When producing the browser-wasm framework ReadyToRun images, crossgen2 crashes while compiling
System.Linq.Parallel. The failing method is the shared-generic instantiation:(and the same for
Pair<int64,int64>), which come fromSystem.Linq.Parallel.The
Execof crossgen2 exits with-532462766(0xE0434352, unhandled managed exception), reported asMSB3073fromMicrosoft.NETCore.App.Runtime.CoreCLR.sfxproj(_CrossgenBrowserFrameworkR2R).Exception
Steps to reproduce
Build the browser-wasm CoreCLR runtime pack (Release), which runs the framework R2R crossgen step:
The crash happens deterministically when crossgen2 compiles
System.Linq.Parallel.wasm. The crossgen2 invocation is roughly:Root cause (confirmed via instrumentation)
The crash is in the JIT importer, not the wasm codegen backend.
Compiler::lookupNamedIntrinsic(src/coreclr/jit/importercalls.cpp) is invoked with a null method handle (CORINFO_METHOD_HANDLE/gtCallMethHnd == NO_METHOD_HANDLE, e.g. an indirect call). It passes that handle straight toinfo.compCompHnd->getMethodNameFromMetadata(method, ...); on the crossgen2 side that doesHandleToObject(ftn)→_handleToObject[index]withindex = ((int)ftn - handleBase) / handleMultiplier. Forftn == 0this is a large negative index →ArgumentOutOfRangeException.Instrumenting crossgen2's
getMethodNameFromMetadataconfirmed the handle value:Returning early from that callback then surfaced a second, identical trap on the same null handle at the
lookupNamedIntrinsicfallbackinfo.compCompHnd->getArrayIntrinsicID(method)(CorInfoImpl.csgetArrayIntrinsicID), proving the bad caller islookupNamedIntrinsicitself.lookupNamedIntrinsichas ~30 call sites, several of which passcall->gtCallMethHndon arbitrary calls (including indirect calls withNO_METHOD_HANDLE, and helper calls whose handle is the odd-encodedeeFindHelpervalue). The wasm framework bubble compiles the shared-generic value-type instantiationAllocateUninitializedArray<Pair<double,long>>(--opt-cross-module:*) where thetypeof(T[])/ array-handling tree reaches one of these sites with a null handle. The bug is latent on other targets that don't compile this exact tree shape.Fix (validated)
Guard
lookupNamedIntrinsicto returnNI_Illegalfor a null or helper handle (neither is ever a named intrinsic), which protects every call site:Validated: with this guard in the rebuilt
clrjit_universal_wasm_x64, crossgen2 compilesSystem.Linq.Parallel.wasmsuccessfully (R2R image emitted, exit 0) instead of crashing.Note
This issue text was generated with the assistance of GitHub Copilot.