Repository navigation
Description
Describe the bug
OloEngine/src/OloEngine/Task/LocalQueue.h's lock-free work-stealing scheduler guards two invariants only with OLO_CORE_ASSERT, which compiles to a pure no-op in Dist builds (Core/Assert.h):
TLocalQueueRegistry::AddLocalQueue()(~line 369-376):u32 Index = m_NumLocalQueues.fetch_add(1, ...)is bounds-checked only via assert beforem_LocalQueues[Index].store(...). In a Dist build, registering more thanMaxLocalQueues(1024) queues writes out of the fixed-sizem_LocalQueuesarray — silent out-of-bounds memory corruption, not a crash.TLocalQueueRegistry::StealItem()(~line 380-384):CachedRandomIndex = CachedRandomIndex % NumQueueswhereNumQueues = m_NumLocalQueues.load(...). There is no guard at all (not even an assert) againstNumQueues == 0— ifStealItemis ever reached before any local queue has registered, this is a division-by-zero in every build config, not just Dist.
SonarQube's S3519 independently flags related out-of-bounds-index patterns in the adjacent Task/NamedThreads.h (m_Queues[...]/m_ThreadIds[...], also assert-only-guarded against a fixed ENamedThread::Count array), consistent with the same assert-elided-bounds-check class — worth a quick audit pass alongside the primary fix, though those arrays are indexed by a compile-time-bounded enum so the blast radius there is smaller than the dynamically-growing LocalQueue index.
To Reproduce
- In a Dist (or otherwise
OLO_CORE_ASSERT-stripped) build, register more thanMaxLocalQueues(1024) local queues viaTLocalQueueRegistry::AddLocalQueue()— e.g. spin up >1024 task-system worker/local queues. - Observe out-of-bounds write into
m_LocalQueuesinstead of a controlled failure. - Separately: call
StealItem()on a registry with zero registered queues (any build config) and observe the% 0divide-by-zero.
Expected behavior
Both invariants should fail safely (early return / release-mode-safe clamp, or a real runtime check that survives Dist builds) instead of corrupting memory or invoking UB, since this is a hot concurrency primitive used engine-wide by the task scheduler.
Additional context
Found via a signal-hygiene sweep of assert-only bounds checks in concurrency primitives during the 2026-07 feature freeze (Tier 2: latent bugs in concurrency code, per docs/agent-rules/sonarqube-review-alignment.md's guidance that SonarQube reliability noise is mostly false positives but real bugs cluster in concurrency primitives). Scope: OloEngine/src/OloEngine/Task/LocalQueue.h primarily, with a smaller audit pass over NamedThreads.h's equivalent pattern.
Score
capability: 3
craft: 3
stability: 5
decay: 3
effort: 3
confidence: 0.7
learning: 2
fun: 2
kano: table-stakes
blocked_by: []
blocks: []
Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort.
Activity
coderabbitai commentedon Jul 10, 2026
🔗 Related PRs
#93 - Port UE5.7 task system to OloEngine [closed]
#318 - feat(physics): powered 3D joint motors + friction (hinge/slider) [merged]
#355 - fix(memory): acquire loads for lock-free allocator page publish/consu… [merged]
#370 - fix(task): drain standby stack atomically in StartShutdown to fix
#35… [merged]#400 - fix(net,task): isfinite-guard untrusted float ingestion (network snap… [merged]
🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
drsnuggles8 commentedon Jul 10, 2026
Fixed in #614.