Repository navigation
Reproduce the restore-time 1224 panic as two live mappings on one scratch - #523
Merged
Merged
Conversation
This was referenced Sep 23, 2026
Owner
Author
This was referenced Sep 23, 2026
thebhef
force-pushed
the
task155-logger-clamp
branch
from
September 24, 2026 01:39
229f9ca to
4f16288
Compare
thebhef
force-pushed
the
task156-restore-crash-investigation
branch
from
September 24, 2026 01:39
8313560 to
33117e1
Compare
This was referenced Sep 24, 2026
thebhef
force-pushed
the
task155-logger-clamp
branch
from
October 7, 2026 14:30
0e4457a to
db0a5b5
Compare
thebhef
force-pushed
the
task156-restore-crash-investigation
branch
from
October 7, 2026 14:30
d15948c to
32bfa20
Compare
This was referenced Oct 8, 2026
thebhef
marked this pull request as ready for review
October 14, 2026 21:08
Owner
Author
thebhef
changed the base branch from
task155-logger-clamp
to
graphite-base/523
October 14, 2026 22:23
…atch The field crash — a tokio worker panicking at seg_chain.rs:76 with Windows OS error 1224 half a second after `restored 57529481 frames from prior capture` — was not a stale in-process store. It was the *previous* cannet process, still alive and still holding every segment file in the same project cache directory while the relaunched one restored that directory and grew a chain in it. A process-wide registry of live mappings, run over the whole cannet-gui and cannet-spill suites, found no production path that keeps two stores or two caches over one directory: there is exactly one TraceStore::new_disk and one SignalCacheStore::new, and every swap path drops the old value before the new one lands. The owner's own log settles it instead — the crashing process started at 17:47:01.954 and panicked at 17:47:09.095, while the process that had just imported that BLF was still emitting its health tick at 17:47:15.902 with its webview already gone. Two processes, fourteen seconds of overlap, one scratch. The collision needs the two chains to be at different lengths, and the manifest guarantees that: the older chain grew into segment i after its last flush, so that file exists and is mapped while the manifest the newer one reopens from still describes a chain one segment short. The newer chain's next push therefore calls create_segment on a live mapping, which opens with truncate(true) and set_len. Both tests here reproduce that in about ten milliseconds against the public API — one over SampleSeq (the pyramid levels), one over DiskRawStore (the by-id postings, the family the field scratch shows). Both fail on every CI OS rather than only on Windows: the Windows arm is the panic, taken with catch_unwind so it reads as an assertion, and the POSIX arm is the assertion that the held chain's samples survive, because there set_len on a mapped file succeeds and silently zeroes the other chain's segment underneath it. Both are #[ignore]d, since making them pass is the fix phase's job; `cargo test --workspace` does not pass --include-ignored, so they stay inert until the attribute comes off. Reviewers should look at what the tests assert rather than how they are shaped: that reopening a segment chain is legal twice over, and that *growing* one is what the fix has to make safe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thebhef
force-pushed
the
task156-restore-crash-investigation
branch
from
October 14, 2026 22:28
32bfa20 to
930a202
Compare
This was referenced Oct 15, 2026
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.

The field crash — a tokio worker panicking at seg_chain.rs:76 with
Windows OS error 1224 half a second after
restored 57529481 frames from prior capture— was not a stale in-process store. It was theprevious cannet process, still alive and still holding every segment
file in the same project cache directory while the relaunched one
restored that directory and grew a chain in it.
A process-wide registry of live mappings, run over the whole cannet-gui
and cannet-spill suites, found no production path that keeps two stores
or two caches over one directory: there is exactly one
TraceStore::new_disk and one SignalCacheStore::new, and every swap path
drops the old value before the new one lands. The owner's own log
settles it instead — the crashing process started at 17:47:01.954 and
panicked at 17:47:09.095, while the process that had just imported that
BLF was still emitting its health tick at 17:47:15.902 with its webview
already gone. Two processes, fourteen seconds of overlap, one scratch.
The collision needs the two chains to be at different lengths, and the
manifest guarantees that: the older chain grew into segment i after its
last flush, so that file exists and is mapped while the manifest the
newer one reopens from still describes a chain one segment short. The
newer chain's next push therefore calls create_segment on a live
mapping, which opens with truncate(true) and set_len.
Both tests here reproduce that in about ten milliseconds against the
public API — one over SampleSeq (the pyramid levels), one over
DiskRawStore (the by-id postings, the family the field scratch shows).
Both fail on every CI OS rather than only on Windows: the Windows arm
is the panic, taken with catch_unwind so it reads as an assertion, and
the POSIX arm is the assertion that the held chain's samples survive,
because there set_len on a mapped file succeeds and silently zeroes the
other chain's segment underneath it. Both are #[ignore]d, since making
them pass is the fix phase's job;
cargo test --workspacedoes not pass--include-ignored, so they stay inert until the attribute comes off.
Reviewers should look at what the tests assert rather than how they are
shaped: that reopening a segment chain is legal twice over, and that
growing one is what the fix has to make safe.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com