fix: a recompute that renumbered its ring, and readouts frozen under a zoom
Three defects, all of them a window describing data that is not there. A math edit refilled the derived ring with `clear()`, which renumbers it from 0, leaving `produced()` short by the inputs' retained base. Since `live_window_locked()` clamps against every channel's `produced()`, that one lagging channel answered `n = 0` for the live view, every pause view and every trigger capture until a whole ring of fresh data had gone by -- the reported freeze, invisible until the ring first wraps, hence its intermittence. It now restarts with `clear_to(base)`, and `ChannelBuffer::republish_from(base)` puts the published window back: `acquire()` is incremental, so a rewrite in place published nothing and the pyramid went on describing the samples the edit replaced. The trigger's channel is an index, re-resolved by name after a renumbering -- but only in `rebuild_enabled_locked()`, so a math add or delete went through `set_math_channels()` with no restore, the index was clamped to -1, and `process()` returned at once while the panel still named the channel. The restore moves into `rebuild_channels()`, which *is* the renumbering, so no caller can forget it. And `update_measures()` suppressed its "the window moved" test while an event was held -- the one mode where a gesture is the only thing that can move it. Zooming a latched event left the pane describing the whole captured event. A pinned window needs no exemption: it lands on the range it already measured and fails the 2 % test by itself. The checks that missed all three: `UDPSCOPE_PROBE_MATHWRAP_MS` edits a graph whose ring has already wrapped, which `math_probe` structurally cannot reach; `[measure-trace]` now prints the mode, the window on screen and the window the numbers describe; and the dump's `marks_in_window` counts against the window on screen instead of against the one the marks were computed over, where it was a tautology. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
074cb611bc
commit
d91957a2fe
15 files changed
+374
-45
No files matched your search
@@ -52,8 +52,15 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
`Acquisition::on_data()` on **every packet** out of `model_.trigger()`. `TriggerConfig::channel`
|
||||
is an index into `channels()`, and that index is not stable: every rebuild of the channel list
|
||||
renumbers it — enabling a signal that sorts before the trigger's own is enough — and
|
||||
`ScopeModel::set_signal_enabled()` re-resolves the trigger by name and writes the *new* index
|
||||
back. Keying the reset on the index therefore made any such rebuild abandon the capture **and
|
||||
**`ScopeModel::rebuild_channels()` re-resolves the trigger by name and writes the *new* index
|
||||
back, for every caller.** It lives there and not at the call sites because the function *is* the
|
||||
renumbering, and a caller that forgot is a trigger that silently stops: the name-based restore
|
||||
used to be in `rebuild_enabled_locked()` alone, so adding or removing a math channel went through
|
||||
`set_math_channels()`'s structural path with no restore at all, `rebuild_locked()` clamped the
|
||||
now-wrong index to `-1`, and `process()` returns at once on a channel of `-1` while the panel went
|
||||
on naming the channel. That is the second half of the "it sometimes does not trigger, even with
|
||||
the trigger on a non-math channel" report. Keying the reset on the index made any such rebuild
|
||||
abandon the capture **and
|
||||
set no hold-off**, so the next edge inside the post window became t0: that is the "the trigger
|
||||
re-triggers during a capture and the hold-off does not apply" defect, and it needed no glitch
|
||||
and no user action beyond enabling a channel. The name changes when the source genuinely
|
||||
|
||||
Reference in new issue
Block a user