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
{{ message }}
Repository navigation
TSan: IncrementalGcStartSweep's test hook reads a block a GC worker is reclaiming #436
The PR runs built on the same commit passed TSan (#425, #429, #434), so it doesn't happen on every run.
Read of size 4 at 0x726c00330618 by main thread:
#0 __hxcpp_gc_incremental_test(int, hx::Object*)
#1 Main_obj::main()
Previous write of size 8 at 0x726c00330618 by thread T1:
#0 memset
#2 void BlockDataInfo::reclaim<false>(BlockDataStats*)
#3 GlobalAllocator::ThreadLoop(int)
Location is heap block of size 1576 allocated by main thread:
#1 GlobalAllocator::AllocMoreBlocks(bool&, bool)
The second report is the same pair the other way round: a write in GlobalAllocator::ThreadLoop to a 1 MB block, after a read of it by __hxcpp_gc_incremental_test on the main thread. T1 is a GC worker that hx::IncrementalDrain started, from an automatic incremental collection that a large allocation set off.
So the test hook on the main thread reads a block's data while a worker is still reclaiming it. The hook is only built with HXCPP_GC_INCREMENTAL_TEST, so this may be the hook reading without waiting for the workers rather than a race a program can hit, but that hasn't been checked. It isn't #430's pattern (LocalAllocator::DoAlloc reading a block AllocMoreBlocks published), which the TSan job no longer reports on ubuntu-26.04.
Next
Check whether __hxcpp_gc_incremental_test waits for the reclaim jobs before it reads block data, and whether anything outside the hook reads blocks the same way.
That's both of the last two runs on main, against none of the four PR runs on the same code (#425, #429, #434, and #426 before its rebase), so it isn't rare.
Activity
dimensionscape commentedon Nov 12, 2026
It failed the same way on main again at c900b35, the same two reports in IncrementalGcStartSweep and nothing else: https://github.com/openfl/libhxcpp/actions/runs/43181689270/job/131058945561
That's both of the last two runs on main, against none of the four PR runs on the same code (#425, #429, #434, and #426 before its rebase), so it isn't rare.