D580 - A watch that killed the run, and a message that said mapped when it meant published
Status: measured Date: 2026-09-07
The diagnostic could not be pointed at the thing it was for
D579 made a guest's runtime mappings readable, so the command buffer
PPSA03416 submits could be dumped. Thirty-two bytes is the dump's fixed
window and the structure is larger, so the next step was
ORBISTOUN_WATCH, which takes an address and a length.
It killed the run before the guest started:
orbistoun: presenting a ps5/cex/base machine
reached ContainerParsed … reached Linked
outcome Crashed { access violation }
snapshot dereferences the address unconditionally.
Its own documentation said it did not - "silent
when the region cannot be read: … an address that is not mapped is an
ordinary mistake rather than a reason to end the run" - directly
above a raw from_raw_parts, with a SAFETY comment
underneath admitting the opposite ("an address outside it faults
here"). Three statements, two of them wrong, in fourteen lines.
That is principle 3 one layer down: a doc promising what the
branch below it never did is the same failure as a message
naming a cause nothing measured, and D385 has the identical shape
(RUNTIME_GLOBALS, where the doc promised zero
and the code did the other thing).
Fixed on both sides, because the absent case is the interesting one
A region that does not exist at entry is recorded as absent rather
than read. changes then asks again after the guest
has stopped - a different answer for anything the guest mapped while it
ran - and reports what is there.
That is not a degraded mode, it is the common one. A command buffer, a descriptor, anything an allocator handed the guest is mapped after entry, so the diagnostic that was built to answer "which slot did nobody fill in?" could never be aimed at any of them. It reads them now:
orbistoun: watched region:
0x7400008a3520+0x100 did not exist when the guest started
0x7400008a3520 0x0000001400010000
0x7400008a3528 0x0010000000000001
0x7400008a3530 0x0000740009200000
…
The readability test moved to
orbistoun_thunk::readable_span, which is what the argument
dump already used for its own fixed window. One answer to "may I
dereference this?", because a second implementation is a second
chance to fault inside the emulator on an address the guest never
touched.
The message said mapped and meant published
Both this and the argument dump reported an address they could not read as being in "no region this run mapped". They had checked no such thing. What they know is that nothing published the span to them, and for months those two came apart across every mapping a guest made at runtime - so a pointer into an ordinary heap structure was reported in the words used for a wild pointer.
The dump now says "in no span this run published as readable, and address-shaped", and the watch says the same. The distinction is not pedantry: it is the difference between the guest is wrong and the tool cannot see there, and this session spent its first hour on a wall that turned out to be the second.
The fault path is untouched.
diagnose.rs reports "an address in no region this run
mapped" about a faulting address, which it establishes from the
trace's own region list rather than from the readable spans. Same words,
different and correct claim.
What it then showed, and the reading was wrong
The command buffer's word at +0x10 is a pointer into the
mapping arena. A watch on that address reported no published span, and
this entry read it as the guest holds a buffer orbistoun never
mapped for it.
It is mapped. Asked from inside the call that
receives the pointer, where the two cannot be a run apart:
0x740009200000..0x740009300000, one mebibyte, exactly the
length the header states. The address had been typed in from a
previous run while the arena moves between runs (D582), so the
pairing was never sound - and "no published span" was read as "not
mapped", which is the distinction this same entry renamed a message to
make.
The caveat below was correct and was the load-bearing part; it is kept as written because being right about the limit and wrong about the conclusion anyway is the whole lesson. The two causes of the non-publication - a write-only mapping recorded as unreadable, and a table of readable ranges that had silently run out of room - are D588.
This is not established as the cause of anything.
The tool distinguishes unmapped from unpublished no
better here than anywhere else - a mapping path that does not go through
mapping_placed would look identical - and only one run was
checked as a matched pair. It is recorded because it is the kind of
thing that gets assumed away. recorded because it is the kind of thing
that gets assumed away.
And the address is not the same twice
Four runs of one build, reading the same word:
| run | +0x10 |
reservations failed |
|---|---|---|
| 1 | 0x740009200000 |
2 |
| 2 | 0x740009100000 |
- |
| 3 | 0x740009200000 |
- |
| 4 | 0x740009200000 |
2 |
Two runs of one build do not agree, which D181 and D238 require of every measurement here. It moves with the reservation conflicts, so the arena's bump allocator is being driven by something that varies. Not diagnosed, and it is the reason a watch has to be aimed by hand at an address read out of a previous run - the automation this entry would otherwise have earned.
What this does not establish
That the fixed watch reads every structure worth reading. It reads one span, given an address a person typed after a previous run printed it. Following a pointer out of a dumped argument is the step that would remove the guessing, and is not attempted here.
Nor that the remaining unreadable pointers are the guest's fault. Nineteen in a run still report the message above; some are host addresses that legitimately are not guest memory, and the split has not been counted.