TLS13-C12: per-phase stack boundaries, and the measured reason the gate is red - #1299
Merged
Merged
Conversation
The gate runs locally (this host is Apple silicon macOS 27), so for the first time the consumer executed as a guest instead of only compiling. It found three faults that no host test could have: the host driver has an 8 MB stack, and every one of these is a stack or ABI problem. 1. `_start`'s frame was 81,264 bytes. `Client` is ~87 KiB and was a stack local; the guest stack is 32 KiB (`scheduler.task_stack_size`), so the guest died on the prologue store at entry+0x40 with a data abort and printed nothing at all. The client and the seam are now file-scope, the same reason the trust store already lived in .bss. 2. `_start` still measured 81,136 bytes after that, because Zig fused the whole call graph into one frame. A `noinline` `serve` boundary brought the entry frame to 208 bytes and made the remaining cost visible instead of diffused. 3. argv was shifted by one. exec.zig's DSK1/DSK3 paths set `argc = args.len` and pack slot 0 with the FIRST USER ARGUMENT; the ELF path sets `argc = 1 + args.len` with `argv_list[0] = name`. The app assumed the ELF shape, skipped slot 0, and read `24533` as an IPv4 literal -- "bad target". It now skips slot 0 only when slot 0 actually is the program name. Evidence after the fixes (local vgate, artifacts/live-tls13-report.txt): serial-contains [fetchs: target set] = 1 (was 0) serial-contains [fetchs: roots loaded] = 0 The run now reaches the consumer body and then faults for a fourth, larger reason, measured rather than guessed (see the next commit): the client's stack footprint, ~79 KiB in one frame, exceeds the 32 KiB guest stack. zig build test: 200/200 steps, 3599/3599 tests.
…te is red The gate now runs locally. This commit records what it measured, so the next person gets a number instead of a mystery. Splitting the consumer into noinline phases did NOT bring the client under budget -- the 79 KiB lives inside a single client function, not in the sum of inlined calls. So the finding is stated as a finding: guest task stack (scheduler.task_stack_size) 32,768 B largest frame in FETCHS.BIN 79,856 B second largest 34,032 B That is a structural property of the client, invisible to every host test because the interop driver has an 8 MB stack, and exactly the class of thing a class-B gate exists to catch. live-tls13.spec carries this as a KNOWN-FAILING block on purpose. It is committed red rather than relaxed: weakening the assertions would hide the defect, and the fix is a real decision -- reduce the client's stack use, or grow the per-task stack (which changes every user task's memory footprint). zig build test: 200/200 steps, 3599/3599 tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #1291. This PR is where the class-B gate finally ran — this host is Apple silicon macOS 27, so
vgate.shbuilds its own runner and boots the image locally.It did not pass. It found four real defects, three of which are fixed here, and the fourth of which is a structural property of the client that no host test could have caught.
Fixed
_start's frame was 81,264 B;Clientis ~87 KiB and was a stack local. The guest died on the prologue store at entry+0x40 and printed nothing._startframe → 208 B)noinline serveboundaryexec.zig's DSK1/DSK3 paths setargc = args.lenand pack slot 0 with the first user argument; the ELF path setsargc = 1 + args.lenwithargv_list[0] = name. The app assumed the ELF shape and read24533as an IPv4 literal.serial-contains [fetchs: target set]0 → 1The open finding, measured
The TLS client's stack footprint exceeds the guest stack. Splitting the consumer into
noinlinephases did not help — the 79 KiB lives inside a single client function, not in the sum of inlined calls.This is invisible to every host test because the interop driver has an 8 MB stack. It is exactly the class of thing a class-B gate exists to catch.
Why the spec is committed red
live-tls13.speccarries aKNOWN-FAILINGblock with these numbers. Weakening the assertions would hide the defect. The fix is a genuine decision:zig build test: 200/200 steps, 3599/3599 tests. CI does not run class-B gates (no runner registered), so this PR is green where the gate is red — which is itself the point.