Repository navigation
fix(net): bump equilibrium for the EBR-guarded map iteration begin - #4
Merged
Merged
Conversation
Force67
force-pushed
the
fix/bump-equilibrium-ebr-begin
branch
from
September 19, 2026 08:15
ce3266b to
bafeba5
Compare
vendor/equilibrium e68c2b8 -> efb03b7: LockFreeOrderedHashMap::begin() walked the bucket chains looking for the first live node before the iterator's ebr::Guard announced -- exactly the nodes a concurrent collect_garbage() pass sweeps, retires and frees. Under sustained reliable-packet + ack churn the preamble could step into freed memory and hand the retry scan a garbage start node, which is the segfault in ZPacketQueue::ProcessOutgoingPackets (z_packet_queues.cc:314) observed in long-running multiplayer sessions: the retry scan faults dereferencing a near-null chain node. order_begin() had the same load-before-announce gap on a smaller window. The bump announces the epoch before the first dereference and keeps the pin continuous into the iterator; the container's existing test suite passes under ASan with the change.
Force67
force-pushed
the
fix/bump-equilibrium-ebr-begin
branch
from
September 19, 2026 08:35
bafeba5 to
9aeefb5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the field crash observed in long-running multiplayer sessions; the container fix lives in Force67/equilibrium#17 (submodule bump only here).
The crash
The reliable-transport retry scan range-fors
awaiting_ack_packets_everyretry interval. Under minutes of gameplay traffic (constant reliable packets +
ack churn) that traversal faulted dereferencing a near-null chain node —
confirmed in core dumps from three separate crashed sessions, with the same
signature each time.
Root cause
LockFreeOrderedHashMap::begin()walked the bucket chains looking for thefirst live node before the iterator's
ebr::Guardannounced. The skippeddeleted-but-not-yet-swept nodes are exactly what a concurrent
collect_garbage()pass unlinks, retires and frees, so the preamble couldstep into freed memory and start the traversal on a garbage node.
order_begin()had the same gap on a smaller window.The bump
vendor/equilibrium e68c2b8 → efb03b7 (Force67/equilibrium#17): announce the
epoch before the first dereference in
begin()/order_begin()and keep theguard pin continuous into the iterator. The container's existing test suite
passes under ASan with the change, and a begin()-under-churn stress
reproducer that faults in the preamble on the parent commit no longer does.
Follow-up
Force67/equilibrium#18 documents a separate, deeper iterator-protocol flaw
(reproducible under duplicate-key insert churn, structural rather than
lifetime-related) with reproducers; it needs its own root-cause pass and does
not block this bump, which fixes the unguarded preamble the production crash
traversed.
Updated 2026-09-19: what this bump now carries
Force67/equilibrium#17 was rebased onto
devel5to clear a conflict, so itscommit changed and this pointer moved with it. The pin here was
e68c2b8, whichturned out to be 25 commits behind
devel5, so this is no longer a one-commitbump: it advances
vendor/equilibriumtodevel5plus the iteration fix, 26commits. The notable ones beyond the fix:
74e85caRemove the STL and the C runtime from base363b036/dc1a10c/3223dd4security bug bash 1-352d4beacontainer value semantics, string search and std view interop3c336fecompile the windows sources with a mingw toolchainf961dcbanOption<const char*>owns the string it is givenVerified locally against this exact pointer, in the configuration that consumes
equilibrium (
-DZNET_USE_STL=OFF):handshake_integrationandmp_integrationpass;passes.
Two notes on merging:
devel5commit. Right now it names the PR branch's head, which a submodule fetch can
only reach while that branch exists.
2026-09-01 (including the two that were merged): the
actions/checkoutstepsin all three workflows lack
submodules: recursive, so no vendored dependencyis present and the build dies on
xxhash.h(which lives invendor/lz4/lib).