Repository navigation
AF: *(_UNCHECKED_OBJECTREF *)handle == NULL (HndCreateHandle called by getJitHandleForObject) #117138
Description
Activity
- addedos-macosmacOS aka OSXmacOS aka OSXblocking-clean-ci-optionalBlocking optional rolling runsBlocking optional rolling runs
on Jun 30, 2025 - addeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jun 30, 2025 - addedneeds-area-labelAn area label is needed to ensure this gets routed to the appropriate area ownersAn area label is needed to ensure this gets routed to the appropriate area owners
on Jun 30, 2025 - 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 Jul 7, 2025 - removedneeds-area-labelAn area label is needed to ensure this gets routed to the appropriate area ownersAn area label is needed to ensure this gets routed to the appropriate area owners
on Jul 7, 2025 - removeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jul 14, 2025 - addedKnown Build ErrorUse this to report build issues in the .NET Helix tabUse this to report build issues in the .NET Helix tab
on Jul 28, 2025 This hasn't hit in the last few runs. Removing blocking-optional tag.
- removedblocking-clean-ci-optionalBlocking optional rolling runsBlocking optional rolling runs
on Jul 28, 2025 16 remaining items
run GC collect in background
You would also need to ensure that there is fragmentation, so the GC compacts the heap, and that the JIT-time handles point to objects that moved around.
would you like me to handle it?
That would be great.
Managed to make a repro out of your idea that fairly quickly hits exactly the same assert (in a matter of seconds):
Assert failure(PID 47728 [0x0000ba70], Thread: 29448 [0x7308]): HndIsNullOrDestroyedHandle(*(_UNCHECKED_OBJECTREF *)handle) CORECLR! BlockFreeHandles + 0x11A (0x00007ffc`9b5ab58a) CORECLR! TableFreeBulkPreparedHandles + 0x112 (0x00007ffc`9b5ace52) CORECLR! TableFullRebalanceCache + 0x1D0 (0x00007ffc`9b648df0) CORECLR! TableFreeSingleHandleToCache + 0x1A9 (0x00007ffc`9b648ba9) CORECLR! HndDestroyHandle + 0x27C (0x00007ffc`9b5aa77c) CORECLR! DestroyHandleCommon + 0x12C (0x00007ffc`9ad87b4c) CORECLR! CEEInfo::~CEEInfo + 0x4D (0x00007ffc`9b034d5d) CORECLR! CEECodeGenInfo::~CEECodeGenInfo + 0x16E (0x00007ffc`9b034cde) CORECLR! CEEJitInfo::~CEEJitInfo + 0x1B8 (0x00007ffc`9b034f78) CORECLR! UnsafeJitFunction + 0x5FD (0x00007ffc`9b04625d) File: C:\prj\runtime-main2\src\coreclr\gc\handletablecore.cpp:1873 Image: C:\prj\runtime-main2\artifacts\bin\coreclr\windows.x64.Checked\corerun.exeor some other runs hit:
Assert failure(PID 47920 [0x0000bb30], Thread: 36844 [0x8fec]): *(_UNCHECKED_OBJECTREF *)handle == NULL CORECLR! HndCreateHandle + 0x21D (0x00007ffc`9b5aa17d) CORECLR! GCHandleStore::CreateHandleOfType + 0xB4 (0x00007ffc`9b6440a4) CORECLR! CEEInfo::getJitHandleForObject + 0x216 (0x00007ffc`9b06fee6) CORECLR! CEEInfo::getStaticObjRefContent + 0x1AC (0x00007ffc`9b077dec) CORECLR! CEEInfo::getStaticFieldContent + 0x374 (0x00007ffc`9b077414) CLRJIT! ValueNumStore::VNForFunc + 0x24B (0x00007ffc`990ced2b) CLRJIT! ValueNumStore::VNPairForFunc + 0x3E (0x00007ffc`990d344e) CLRJIT! Compiler::fgValueNumberTree + 0xC40 (0x00007ffc`991206a0) CLRJIT! Compiler::fgValueNumberBlock + 0x772 (0x00007ffc`99119a72) CLRJIT! Compiler::fgValueNumberBlocks + 0x259 (0x00007ffc`99119e99) File: C:\prj\runtime-main2\src\coreclr\gc\handletable.cpp:306 Image: C:\prj\runtime-main2\artifacts\bin\coreclr\windows.x64.Checked\corerun.exeRepro.cs (static readonly array (non-frozen object) + length access generates jit-time handles) + a thread with GC.Collect (poor man's GCStress) + a thread with GC pressure + several config knobs:
$env:DOTNET_TieredCompilation=0 $env:DOTNET_GCHeapHardLimit=0x100000and if the repro is spinned in a loop:
$iteration = 0 while ($true) { $iteration++ Write-Host "--- Iteration $iteration ---" -ForegroundColor Yellow & "C:\prj\runtime-main2\artifacts\bin\coreclr\windows.x64.Checked\corerun.exe" "$PSScriptRoot\net11\ConsoleApp25_11.dll" if ($LASTEXITCODE -ne 0) { Write-Host "FAILED on iteration $iteration with exit code $LASTEXITCODE" -ForegroundColor Red break } }
Reacted by Jan KotasCan confirm
GCX_COOPinsidevirtual ~CEEInfo()makes bug go awayReacted by Jan Kotas@jkotas for
The simplest fix may be to require DestroyHandle to be called in cooperative mode.
It seems we call DestroyHandle from many places and it's not trivial to trace what GC modes are used for that (especially for various destructors), can we just switch to COOP inside
DestroyHandleCommonitself? or it's an overhead for cases where it's already in COOP?My AI-driven attempt to use COOP in all callers: 6cedb0c
it's an overhead for cases where it's already in COOP?
Yes, for the GCHandle FCalls in particular. I expect that the extra GCX_COOP will show up in micro-benchmarks.
Also, I suspect we may need to do a bit of refactoring around some of the destructors. They may be called in a place where it is not possible to switch GC modes.
My AI-driven attempt to use COOP in all callers: 6cedb0c
Is this all? It does not look too bad.
Failed in:
Console Log: Console Log
Source: runtime-coreclr libraries-pgo / net11.0-linux-Release-x64-defaultpgo-AzureLinux.3.Amd64.Open / System.Text.Json.TestsFailed tests:
- net11.0-linux-Release-x64-defaultpgo-AzureLinux.3.Amd64.Open - System.Text.Json.Tests- added a commit that references this issue
on May 27, 2026 - addedblocking-clean-ci-optionalBlocking optional rolling runsBlocking optional rolling runs
on Jun 8, 2026 - marked Assert failure: *(_UNCHECKED_OBJECTREF *)handle == NULL in System.Memory.Tests #129956 as a duplicate of this issue
on Jun 29, 2026 Failed in (1):
Console Log: Console Log
Source: runtime-coreclr libraries-pgo / net11.0-windows-Release-x64-jitosr_stress-Windows.10.Amd64.Open / System.Runtime.Numerics.TestsFailed tests:
- net11.0-windows-Release-x64-jitosr_stress-Windows.10.Amd64.Open - System.Runtime.Numerics.TestsError Message:
Assert failure(PID 9492 [0x00002514], Thread: 11336 [0x2c48]): *(_UNCHECKED_OBJECTREF *)handle == NULL CORECLR! HndCreateHandle + 0x21D (0x00007ffe`3767566d) CORECLR! GCHandleStore::CreateHandleOfType + 0xBF (0x00007ffe`3768191f) CORECLR! Thread::SetLastThrownObject + 0x3CD (0x00007ffe`3724be6d) CORECLR! Thread::SafeSetThrowables + 0x207 (0x00007ffe`3724a6f7) CORECLR! NotifyExceptionPassStarted + 0xB2 (0x00007ffe`3765c8c2) CORECLR! SfiInitWorker + 0x165 (0x00007ffe`3765de85) CORECLR! SfiInit + 0x23F (0x00007ffe`37661b2f) SYSTEM.PRIVATE.CORELIB! <no symbol> + 0x0 (0x00007ffe`359819d7) SYSTEM.PRIVATE.CORELIB! <no symbol> + 0x0 (0x00007ffe`359817cb) CORECLR! UnmanagedCallersOnlyCaller::InvokeDirect<unsigned long,ExInfo *> + 0x1E8 (0x00007ffe`37075eb8) File: D:\a\_work\1\s\src\coreclr\gc\handletable.cpp:306 Image: C:\h\w\AC280905\p\dotnet.exeFailed in: runtime-coreclr libraries-jitstress2-jitstressregs 20260711.1
Failed tests:
net11.0-linux-Release-x64-jitstress2_jitstressregs0x10-AzureLinux.3.Amd64.Open - System.Reflection.MetadataLoadContext.Tests Work ItemError message:
ASSERT FAILED Expression: *(_UNCHECKED_OBJECTREF *)handle == NULL Location: /__w/1/s/src/coreclr/gc/handletable.cpp:306 Function: HndCreateHandle Process: 38944 [createdump] Gathering state for process 38944 dotnet [createdump] Crashing thread 9837 signal 5 (0005) [createdump] Writing crash report to file /datadisks/disk1/dumps/coredump.38944.dmp.crashreport.json [createdump] Crash report successfully written [createdump] Writing minidump with heap to file /datadisks/disk1/dumps/coredump.38944.dmp [createdump] Written 201654272 bytes (49232 pages) to core file [createdump] Target process is alive [createdump] Dump successfully written in 1063ms waitpid() returned successfully (wstatus 00000000) WEXITSTATUS 0 WTERMSIG 0 ./RunTests.sh: line 175: 38944 Aborted (core dumped) "$RUNTIME_PATH/dotnet" exec --runtimeconfig System.Reflection.MetadataLoadContext.Tests.runtimeconfig.json --depsfile System.Reflection.MetadataLoadContext.Tests.deps.json xunit.console.dll System.Reflection.MetadataLoadContext.Tests.dll -xml testResults.xml -nologo -nocolor -notrait category=IgnoreForCI -notrait category=OuterLoop -notrait category=failing $RSP_FILE /datadisks/disk1/work/BD7C09D2/w/ACBC094D/e ----- end Sat Jul 11 09:59:51 AM UTC 2026 ----- exit code 134 ----------------------------------------------------------- added a commit that references this issue
on Jul 15, 2026 I just hit this in pri 0 tests without stress.
Failed in: runtime-coreclr gcstress-extra 20260906.1
Failed tests:
coreclr osx arm64 Checked gcstress0xc_jitstress2 @ OSX.26.Arm64.Open - JIT/Regression/JitBlue/DevDiv_461649/DevDiv_461649/DevDiv_461649.cmdError message:
ASSERT FAILED Expression: *(_UNCHECKED_OBJECTREF *)handle == NULL Location: /Users/runner/work/1/s/src/coreclr/gc/handletable.cpp:301 Function: HndCreateHandle Process: 2120 /private/tmp/helix/working/B09D09D3/w/9FB30918/e/JIT/Regression/Regression_3/../JitBlue/DevDiv_461649/DevDiv_461649/DevDiv_461649.sh: line 462: 2120 Trace/BPT trap: 5 (core dumped) $LAUNCHER $ExePath "${CLRTestExecutionArguments[@]}" Return code: 1 Raw output file: /tmp/helix/working/B09D09D3/w/9FB30918/uploads/JitBlue/DevDiv_461649/DevDiv_461649/output.txt Raw output: BEGIN EXECUTION /tmp/helix/working/B09D09D3/p/corerun -p System.Reflection.Metadata.MetadataUpdater.IsSupported=false -p System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization=true DevDiv_461649.dll '' Expected: 100 Actual: 133 END EXECUTION - FAILED Test Harness Exitcode is : 1 To run the test: Set up CORE_ROOT and run. > /private/tmp/helix/working/B09D09D3/w/9FB30918/e/JIT/Regression/Regression_3/../JitBlue/DevDiv_461649/DevDiv_461649/DevDiv_461649.shStack trace:
at TestLibrary.OutOfProcessTest.RunOutOfProcessTest(String assemblyPath, String testPathPrefix) in /__w/1/s/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs:line 82 at Program.<<Main>$>g__TestExecutor108|0_109(StreamWriter tempLogSw, StreamWriter statsCsvSw, StreamWriter outOfProcessPlanWriter, <>c__DisplayClass0_0&)
Failed in: runtime-coreclr gcstress-extra 20250629.1
Failed tests:
Build Information
Build: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1081377&view=results
Build error leg or test failing:
Error Message
Fill the error message using step by step known issues guidance.
{ "ErrorMessage": "*(_UNCHECKED_OBJECTREF *)handle == NULL", "BuildRetry": false, "ExcludeConsoleLog": false }Known issue validation
Build: 🔎⚠️ Validation could not be done without an Azure DevOps build URL on the issue. Please add it to the "Build: 🔎" line.
Result validation:
Validation performed at: 9/28/2025 6:05:32 PM UTC
Report
Summary