re: the freeze is not a kernel-object wait -- log_stuck_waits stays silent

The canary branch already carries log_stuck_waits, written for this exact
question: it names the object a guest thread keeps timing out on, and is silent
on a healthy run because a wait that gets satisfied never builds a streak.

Enabled it and ran to the freeze on the stock build.  Not one stuck-wait line,
alongside the usual AllocRange failure and guest throw.  So no guest thread is
parked on a kernel object that never gets signalled; combined with 389% CPU
across running threads, the guest is spinning in its own code -- which is what
the throw-that-returns predicts, since execution resumes after the throw and
runs into code that assumed it would not.

Operational note worth having: --log_stuck_waits=true on the command line is
ACCEPTED but the config file value wins, and the first run silently logged
"log_stuck_waits = false" while I thought it was on.  The startup dump prints
the effective value -- check the dump, not the flag.  The flag is cheap and
silent so it is now left enabled in the container config.
This commit is contained in:
Sylpheed RE agent
2026-08-26 16:10:07 +00:00
parent b24264ef5c
commit a65649598e

View File

@@ -392,3 +392,35 @@ Checked with the 209-vs-67 000 byte log signature for a rejected argument:
`--eh_dispatch` (named in `newgame_path.sh` and `title-crash-stl-tree.md`),
`--mem_watch` (passed by `newgame_path.sh`), and `--audio`. All three are
silently rejected, which blocks boot entirely rather than warning.
## 🔴 It is not a kernel-object wait — `log_stuck_waits` is silent
The canary branch already carries `log_stuck_waits`, written for exactly this
question: it names the object a guest thread keeps timing out on, and its own
help records that it is *"silent on a healthy run — a wait that is being
satisfied never builds a streak"*.
Turned on (via the config file — a `--log_stuck_waits=true` on the command line
is accepted but the config value wins, and the startup dump shows which you got,
so **check the dump rather than trusting the flag**) and run through to the
freeze on the stock build:
log_stuck_waits = true
!> PhysicalHeap::AllocRange unable to alloc ... (requested 134217728 bytes, parent free 28969/131072)
!> Guest attempted to throw a C++ exception!
**Not one stuck-wait line.** So no guest thread is parked on a kernel object that
never gets signalled. Combined with 389 % CPU across running threads, the guest
is *spinning in its own code*, which is what the throw-that-returns predicts:
execution resumes after the throw and runs on into code that assumed it would
not.
That leaves the two paths clearly separated:
| build | allocation | exception | stuck wait | outcome |
|---|---|---|---|---|
| stock | **fails** at 128 MB | **thrown**, does not unwind | none | frozen |
| GPU-writeback shrunk to 1 MB | succeeds | none | none | frozen **earlier** |
The flag is cheap and silent, so it has been **left enabled** in the container's
`xenia-canary.config.toml`.