re: control run withdraws the T68/T69 signature too -- nothing survives

Six captures across one healthy run: 12 thread states stable, 13 vary. Every
thread previously reported as a freeze signature is in the VARIES set --
including T68/T69, which I had kept as 'what reproduces across both freezes'.
They park and unpark during ordinary play, landing on the same objects they hold
when frozen, so seeing them parked while frozen is not evidence.

Net: no thread-level freeze signature has survived. Both frozen diffs are
consistent with healthy variation, and one-sample-per-state was never capable of
separating them.

Still standing: the 12 stable threads hold the same object in all six captures
and none of them moved in either frozen capture -- so 'not a whole-emulator
stall' survives, now resting on the stable set being undisturbed rather than on
a count of unchanged threads.

Also noted: gdb thread numbers are not comparable across runs (this run has
T132-T142, earlier runs had T104-T106), so future cross-run work must key on the
object address or guest thread id.
This commit is contained in:
Sylpheed RE agent
2026-08-25 11:07:37 +00:00
parent fa57338af8
commit 1772d94558
2 changed files with 84 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
=== stability across 6 healthy captures: h1, h2, h3, h4, h5, h6 ===
T142 VARIES Wait(XEvent) | -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T141 VARIES -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T140 VARIES -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T139 VARIES -- | Wait(XEvent) | -- | -- | -- | --
T133 STABLE Wait(XEvent)
T132 VARIES Wait(XEvent) | -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T80 STABLE WaitMultiple(XEvent,XSemaphore)
T79 STABLE WaitMultiple(XEvent,XSemaphore)
T78 VARIES WaitMultiple(XEvent,XSemaphore) | Wait() | WaitMultiple(XEvent,XSemaphore) | WaitMultiple(XEvent,XSemaphore) | WaitMultiple(XEvent,XSemaphore) | WaitMultiple(XEvent,XSemaphore)
T77 STABLE Wait(XEvent)
T76 STABLE WaitMultiple(XEvent,XTimer)
T75 VARIES Wait(XSemaphore) | -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T74 VARIES Wait(XSemaphore) | -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T71 STABLE Wait(XEvent)
T69 VARIES -- | -- | -- | Wait(XSemaphore) | -- | Wait(XSemaphore)
T68 VARIES -- | -- | -- | Wait(XEvent) | -- | Wait(XEvent)
T67 VARIES -- | -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T66 STABLE Wait(XEvent)
T65 STABLE WaitMultiple(XEvent,XSemaphore)
T64 STABLE WaitMultiple(XEvent,XSemaphore)
T63 STABLE Wait(XSemaphore)
T62 STABLE Wait(XEvent)
T61 STABLE Wait(XEvent)
T50 VARIES -- | -- | Wait(XEvent) | Wait(XEvent) | Wait(XEvent) | Wait(XEvent)
T36 VARIES WaitMultiple(XEvent,XEvent) | WaitMultiple(XEvent,XEvent) | WaitMultiple(XEvent,XEvent) | -- | WaitMultiple(XEvent,XEvent) | --
--- 12 stable, 13 vary across healthy play
Only a thread in the STABLE set can carry a frozen-state signature;
a VARIES thread differing when frozen proves nothing.

View File

@@ -1090,3 +1090,58 @@ Data: `data/waitobj-s02.txt` (run 1), `data/waitobj-s02-inducer.txt` (run 2).
cannot say. The fix for the error above applies here too — **repeat the capture
several times within a single healthy run** to learn which thread states are
stable before reading any frozen diff as meaningful.
## 🔴 2026-08-25 — the control run kills the signature: NOTHING survives
Six wait-object captures across a **single healthy run**, 40 s apart, to learn
which thread states are stable before reading any frozen diff as meaningful
(`data/waitobj-healthy-stability.txt`). The answer is that most are not:
```
12 stable, 13 vary across healthy play
```
**Every thread I had reported as a freeze signature is in the VARIES set.**
| thread | across six *healthy* captures |
|---|---|
| T74, T75 | `Wait(XSemaphore)``--``Wait(XEvent)` ×4 |
| T68 | `--`, `--`, `--`, `Wait(XEvent)`, `--`, `Wait(XEvent)` |
| T69 | `--`, `--`, `--`, `Wait(XSemaphore)`, `--`, `Wait(XSemaphore)` |
| T50, T67, T36 | drift in and out of a wait |
So the T74/T75 withdrawal was right — and **T68/T69, which I kept as "what
reproduces across both freezes", is withdrawn too.** Those two threads park and
unpark repeatedly during ordinary play, including landing on exactly the objects
they held when frozen. Seeing them parked in a frozen capture is not evidence of
anything.
**Net: no thread-level freeze signature has survived.** Both frozen diffs are
consistent with healthy variation, and the method as run — one sample per state —
was never capable of telling them apart. Two iterations of "the thing to chase"
were noise.
### ✅ What is still standing
* The **12 stable threads** — T133, T80, T79, T77, T76, T71, T66, T65, T64, T63,
T62, T61 — hold the same object in all six captures. **Only these can carry a
signature.** In both frozen captures, none of them moved, which is what
"17 of 24 / 21 of 24 unchanged" was really measuring.
* So **"the freeze is not a whole-emulator stall" survives** — but it now rests
on the stable set being undisturbed, not on the count of unchanged threads.
### ⚠️ And gdb thread numbers are not comparable across runs
This run's threads include T132T142, which no earlier run had, while earlier
runs had T104T106 that this one does not. Thread *numbering* is per-process, so
a "T74" in two runs need not be the same guest thread. Every comparison so far
was within one run, which is sound — but any future cross-run comparison must key
on something else (the object address, or the guest thread id), not the gdb
number.
### What would actually work
Compare **distributions**, not samples: N healthy captures vs N frozen ones, and
call a thread a signature only if its frozen distribution lies outside its
healthy range. The harness now does the healthy half; the frozen half needs a run
that freezes while being sampled repeatedly.