a73x

86003eb5

feat: valgrind 6c first run — clean bill; pin local stack to x86_64_v3

a73x   2026-08-14 10:28

Commit message
feat: valgrind 6c first run — clean bill; pin local stack to x86_64_v3

valgrind 3.25 decodes no AVX-512: the first run SIGILL'd in Zig's
sigemptyset (native Zig codegen), and after -Dcpu=x86_64_v3 on the Zig
side, again in wolfSSL's vectorized memset (native zig cc codegen in the
deps). deps/quic's zigcc-native wrapper now pins -march=x86_64_v3 —
nothing shipped changes (musl target was baseline already), and the
local dev stack becomes valgrindable. Run result: definitely lost 0,
indirectly lost 0, 0 errors over daemon lifecycle + QUIC attach +
SIGTERM teardown. Recipe usage header states the -Dcpu requirement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

deps/quic/build-deps.sh
Old New
@@ -44,9 +44,15 @@ command -v curl >/dev/null || { echo "deps/quic: curl is required" >&2; exit 1;
44 echo "deps/quic: building the QUIC stack for $T (first run: downloads ~30MB, takes a few minutes)" >&2 44 echo "deps/quic: building the QUIC stack for $T (first run: downloads ~30MB, takes a few minutes)" >&2
45 mkdir -p "$W/src" "$W/bin" 45 mkdir -p "$W/src" "$W/bin"
46 46
47 # x86_64_v3, not native: valgrind 3.25 decodes no AVX-512, and a host
48 # CPU that has it would otherwise bake EVEX into wolfSSL's memset —
49 # making the whole local stack un-valgrindable (found by 6c's first run).
50 # v3 (AVX2) costs nothing measurable at terminal bandwidth, and the musl
51 # release target below is baseline anyway, so nothing shipped changes.
52 # Zig-style CPU name (underscores): zig cc rejects clang's x86-64-v3.
47 cat > "$W/bin/zigcc-native" <<EOF 53 cat > "$W/bin/zigcc-native" <<EOF
48 #!/bin/sh 54 #!/bin/sh
49 exec $ZIG cc "\$@" 55 exec $ZIG cc -march=x86_64_v3 "\$@"
50 EOF 56 EOF
51 cat > "$W/bin/zigcc-musl" <<EOF 57 cat > "$W/bin/zigcc-musl" <<EOF
52 #!/bin/sh 58 #!/bin/sh
docs/decisions.md
Old New
@@ -3207,12 +3207,24 @@ two dialects.
3207 compiler's native strictness (unused locals/params, shadowing) already 3207 compiler's native strictness (unused locals/params, shadowing) already
3208 owns the highest-value lint classes; re-try when the pin moves to 3208 owns the highest-value lint classes; re-try when the pin moves to
3209 0.16.x, the version zlint now targets. 3209 0.16.x, the version zlint now targets.
3210 - **valgrind first run (2026-08-14): pending install.** 3210 - **valgrind first run (2026-08-14): clean.** Recipe at
3211 Recipe at tools/valgrind-quic.sh, non-gating (10-50x slowdown distorts every 3211 tools/valgrind-quic.sh, non-gating (10-50x slowdown distorts every timing
3212 timing path). `sudo -n pacman -S --noconfirm valgrind` was refused with 3212 path). Run under valgrind 3.25.1 after the interactive install:
3213 `sudo: a password is required` (exit 1): this box grants no non-interactive 3213 `definitely lost: 0 bytes in 0 blocks`, `indirectly lost: 0`,
3214 sudo, so the run half is pending install. valgrind not installable 3214 `ERROR SUMMARY: 0 errors` — a clean bill over the daemon lifecycle
3215 non-interactively; run `sudo pacman -S valgrind` then the script. 3215 including wolfSSL/ngtcp2 init, a real QUIC attach, and SIGTERM teardown.
3216 The muxa `run` itself timed out at 60s under the slowdown (the handshake
3217 and status frames completed — muxa got a live `at_prompt` answer over
3218 QUIC; only the command await outlasted its window), which the recipe
3219 absorbs by design: the summary is the product, not the probe's exit.
3220 Two environmental findings from getting there, both now codified:
3221 valgrind 3.25 decodes no AVX-512, so (1) the Zig side must be built
3222 `zig build -Dcpu=x86_64_v3` (stated in the recipe's usage header), and
3223 (2) deps/quic's zigcc-native wrapper now pins `-march=x86_64_v3`
3224 permanently — a native-CPU build on an AVX-512 box baked EVEX into
3225 wolfSSL's memset and SIGILL'd instantly under valgrind. v3 costs nothing
3226 measurable at terminal bandwidth and the musl release target was
3227 baseline all along, so nothing shipped changes.
3216 - **The layer table is the law.** build.zig's module graph is declared data: 3228 - **The layer table is the law.** build.zig's module graph is declared data:
3217 a table row per module (name, root, frozen stratum, production imports, 3229 a table row per module (name, root, frozen stratum, production imports,
3218 test-only imports), the wiring loop derives every grant, and a production 3230 test-only imports), the wiring loop derives every grant, and a production
tools/valgrind-quic.sh
Old New
@@ -9,8 +9,11 @@
9 # the QUIC stack or bumping deps/quic. 9 # the QUIC stack or bumping deps/quic.
10 # 10 #
11 # Usage: tools/valgrind-quic.sh [path/to/muxd [path/to/muxa]] 11 # Usage: tools/valgrind-quic.sh [path/to/muxd [path/to/muxa]]
12 # (defaults to zig-out/bin — run `zig build` first; Debug build is the 12 # (defaults to zig-out/bin — build first with `zig build -Dcpu=x86_64_v3`;
13 # point: Zig debug builds carry valgrind client requests natively) 13 # valgrind 3.25 decodes no AVX-512, and a native build on a machine that
14 # has it SIGILLs at startup. The QUIC deps' zigcc-native wrapper already
15 # pins x86_64_v3 for the same reason. Debug build is the point: Zig debug
16 # builds carry valgrind client requests natively.)
14 set -eu 17 set -eu
15 MUXD="${1:-zig-out/bin/muxd}" 18 MUXD="${1:-zig-out/bin/muxd}"
16 MUXA="${2:-zig-out/bin/muxa}" 19 MUXA="${2:-zig-out/bin/muxa}"