chore: bump deps/plotter to the slope-graded polyline, untrack the sdd report
.superpowers/sdd/ is scratch and gitignored; that one report was tracked by accident in an earlier phase. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
ec8eae0317
commit
2b89f72960
2 files changed
+1
-101
No files matched your search
@@ -1,100 +0,0 @@
|
|||||||
# Final Fixes Report
|
|
||||||
|
|
||||||
## Fix 1 — `known_sources()` round-trip check
|
|
||||||
**File:** `src/layout_store.cpp`
|
|
||||||
|
|
||||||
Changed the port parse to capture the end pointer and check `*end != '\0'`, then added a round-trip guard: `sanitize(host) + "_" + std::to_string(port) != stem` rejects any filename that `layout_path()` could not have written. This prevents `foo_8000x.toml` from being listed as `foo:8000` (whose `×` would unlink `foo_8000.toml`) and `_8000.toml` from yielding an empty host (whose `sanitize("")` round-trips to `__8000`). Also fixed include order (`<cstdio>` before `<cstdlib>` — Fix 6) and updated the `multicast`/`interface` comment to state the TOML rule directly rather than pointing at an adjacent comment (Fix 5).
|
|
||||||
|
|
||||||
## Fix 2 — use-after-free: form outliving chooser, unguarded timeout
|
|
||||||
**File:** `src/source_dialog.cpp`
|
|
||||||
|
|
||||||
(a) Added form destruction at the top of `chooser_finish()`: null the pointer first (so `close-request` cannot re-enter), then `gtk_window_destroy()` the form. Any path that finishes the chooser while the form is up — a row click, Escape — previously left a window with four handlers bound to a dead stack frame.
|
|
||||||
|
|
||||||
(b) Stored the id from `g_timeout_add()` for `pick_probe` in `pick_probe_id` and called `g_source_remove(pick_probe_id)` after `g_main_loop_run()` returns (guarded on non-zero). A row picked before the timeout fires would otherwise leave an armed source on the default main context pointing at the gone frame.
|
|
||||||
|
|
||||||
## Fix 3 — false comment on empty-list placeholder
|
|
||||||
**File:** `src/source_dialog.cpp`
|
|
||||||
|
|
||||||
Replaced the false "Not a GtkListBoxRow, so it cannot be activated..." comment with the truth: GTK4 auto-wraps any non-row widget, but the wrapped row carries no `"source-index"` data, so `g_object_get_data()` returns null and `on_row_activated`'s bounds check refuses it.
|
|
||||||
|
|
||||||
## Fix 4 — unreachable duplicate branch in `pick_probe()`
|
|
||||||
**File:** `src/source_dialog.cpp`
|
|
||||||
|
|
||||||
Removed the second `row == nullptr` guard; the `c.known.empty()` guard above it was the only case that produced a null row from the real list. Two identical print statements for one cause made the probe output ambiguous.
|
|
||||||
|
|
||||||
## Fix 5 — cross-reference comment in `save_layout()`
|
|
||||||
**File:** `src/layout_store.cpp`
|
|
||||||
|
|
||||||
Replaced "for the same reason as `enabled` below" with the rule itself: a bare TOML key written after a `[[table]]` header belongs to that table, with `enabled` named as the historical example of where this lost a key.
|
|
||||||
|
|
||||||
## Fix 6 — include ordering
|
|
||||||
**File:** `src/layout_store.cpp`
|
|
||||||
|
|
||||||
Swapped `<cstdlib>` and `<cstdio>` back into alphabetical order.
|
|
||||||
|
|
||||||
## Fix 7 — CLAUDE.md probe text
|
|
||||||
**File:** `CLAUDE.md`
|
|
||||||
|
|
||||||
Fixed `picked nothing` → `picked nothing: the list is empty` to match the exact stderr output. Fix 4 did not change the emitted text, so no further adjustment needed.
|
|
||||||
|
|
||||||
## Fix 8 — dead-port run must not overwrite a configured session
|
|
||||||
**Files:** `src/ui.cpp`, `CLAUDE.md`, `README.md`
|
|
||||||
|
|
||||||
Added `if (app.model->signals().empty()) return;` in `save_layout_now()`, immediately after the `source_port == 0` guard. A run that receives no CONFIG has an empty signal list and must not overwrite a file that holds real signal names — doing so produces `signals = ["", ...]`, which the chooser's filter refuses, silently removing the source from the list. Also deleted all 116 flattened `~/.config/udpscope/*.toml` files (confirmed all had no named signal). Updated CLAUDE.md (chooser invariant section) and README.md (source-chooser paragraph) to document the rule.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
### 1. Build
|
|
||||||
```
|
|
||||||
cmake --build build
|
|
||||||
```
|
|
||||||
Output: clean, only the three pre-existing warnings (unused `output_built`, two missing-field-initializer on `MathNode`).
|
|
||||||
|
|
||||||
### 2. `/tmp/check_sources` (two new assertions added)
|
|
||||||
```
|
|
||||||
g++ -std=c++20 -Isrc -Ideps/plotter/include /tmp/check_sources.cpp src/layout_store.cpp src/math_channel.cpp src/measure.cpp -o /tmp/check_sources
|
|
||||||
/tmp/check_sources
|
|
||||||
```
|
|
||||||
Output:
|
|
||||||
```
|
|
||||||
a session with no named signal is not listed ok
|
|
||||||
newest first ok
|
|
||||||
oldest last ok
|
|
||||||
the stored group comes back ok
|
|
||||||
the row and signal counts are the file's ok
|
|
||||||
the filename splits at the last underscore ok
|
|
||||||
forget_source reports success ok
|
|
||||||
forget_source removes exactly one ok
|
|
||||||
foo_8000x.toml is not listed (trailing 'x' in port) ok
|
|
||||||
_8000.toml is not listed (empty host does not round-trip) ok
|
|
||||||
all ok
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. `/tmp/check_layout_rt`
|
|
||||||
```
|
|
||||||
/tmp/check_layout_rt
|
|
||||||
```
|
|
||||||
Output: all 11 assertions `ok`.
|
|
||||||
|
|
||||||
### 4. End-to-end chooser + scope run
|
|
||||||
```
|
|
||||||
UDPSCOPE_PROBE_PICK_MS=800 UDPSCOPE_EXIT_AFTER_MS=6000 ./build/udpscope
|
|
||||||
```
|
|
||||||
Relevant output:
|
|
||||||
```
|
|
||||||
[sources] picked 127.0.0.1:8000 multicast= interface=
|
|
||||||
[udpscope] layout loaded from /tmp/fix-e2e/udpscope/127.0.0.1_8000.toml
|
|
||||||
[udpscope] frames=817 packets=818 gaps=0 channels=1 span=1677.722s stride=1
|
|
||||||
[udpscope] layout over 476 frames: axes.x 135..147, axes.w 722..734, viewport.w 870..870, y-gutter 88..100, x-ticks 20..21, x-desync 0
|
|
||||||
[udpscope] trace ink: 406 paints checked, 0 collapsed, 0 staircase, 0 short, worst cover 2.5%
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Fix 8 dead-port assertion
|
|
||||||
```
|
|
||||||
timeout 15 xvfb-run -a env XDG_CONFIG_HOME=/tmp/fix-e2e UDPSCOPE_EXIT_AFTER_MS=4000 ./build/udpscope --server 127.0.0.1 --port 8000
|
|
||||||
cat /tmp/fix-e2e/udpscope/127.0.0.1_8000.toml
|
|
||||||
```
|
|
||||||
File mtime stayed at 10:01 (written by the live mock run); the dead-port run at 10:02 did not touch it.
|
|
||||||
File contents: `signals = ["sine", "", "", ""]` — the configured signal name was preserved.
|
|
||||||
Vendored
+1
-1
Submodule deps/plotter updated: cc908efa36...37e414bcc5.
Reference in new issue
Block a user