You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Build-time physics check for form-X binaries (rules A/B): fail at link time instead of crashing at run time #396
xlings' closure design (openxlings/xlings .agents/docs/2026-08-09-ecosystem-closure-design.md) defines three enforcement points for the runtime-closure contract. Points 1 (index CI) and 2 (xlings client, install-time, warn-only) landed on 2026-08-09. Point 3 is mcpp's, because mcpp's default toolchain config is what puts user binaries into form X:
A form-X binary (our loader + our libc) has no host fallback: our ld.so's compiled-in cache path exists on no machine, so any host library entering the process resolves only by RPATH — or fails at run time with an error that names neither the package nor the cause. #392 is this exact shape: host libtinfo.so.6 entered via the GL/GLX chain, our glibc 2.39 could not serve GLIBC_2.42, and the user saw a symbol-version error pointing at a library they never chose.
What point 3 should check (physics only, NO policy)
At link time, for the binary just produced:
Rule B (same-source): the PT_INTERP the driver injected and the libc.so.6 that RPATH will resolve must come from one glibc payload. Mixing (host interp + our libc, or two payload versions) is a pre-main crash with a GLIBC_PRIVATE / vDSO message.
Rule A (version floor): if the link pulled in ANY host library (-l resolved outside the xlings store), then our_glibc >= host_glibc must hold — glibc is backward-compatible only.
Deliberately not checked: whether the user links host libraries at all. That is the user's choice (xlings rule D applies to index packages only). Point 3 can therefore fail hard from day one — everything it rejects is a binary that cannot run.
Suggested failure messages (from the design doc, C2.4)
rule B: PT_INTERP comes from glibc@2.39 but RPATH resolves libc from glibc@2.44 —
one process cannot have two libcs.
rule A: this binary is anchored to glibc 2.39 while the host is 2.43 and the link
pulled in host libtinfo.so.6 — symbols up to GLIBC_2.43 may be required.
Fix: use a runtime >= the host (xlings subos new <name> --runtime glibc@2.44).
Mitigations already landed on the xlings side (2026.8.9.1)
glibc latest and the default subos runtime moved 2.39 → 2.44 (new subos only; existing subos keep their recorded binding).
subos_info.host_glibc now records the host glibc at subos creation — a probe point 3 can reuse instead of probing PATH (getconf on PATH can be a shim; use /usr/bin/getconf GNU_LIBC_VERSION).
These remove the common triggers, but they do not remove the class: any host library newer than the chosen runtime reproduces it, and only the build tool sees the link set early enough to say so.
Draft implementation checkpoint: PR #400 adds exact glibc payload lookup plus Rule A/Rule B validation, sticky post-link verdicts, and mcpp doctor reuse of the stored result. Focused runtime-physics tests and E2E #206 pass locally. The issue remains open until review, normal merge, release, and fresh released-artifact verification complete.
Activity
test(e2e)+docs: register two tests that never ran; fold the day's mea…
test(e2e)+docs: register two tests that never ran; fold the day's mea…
feat(closure): C1 default-runtime binding + C2 install-time guard (20…
Sunrisepeak commentedon Aug 9, 2026
Draft implementation checkpoint: PR #400 adds exact glibc payload lookup plus Rule A/Rule B validation, sticky post-link verdicts, and
mcpp doctorreuse of the stored result. Focused runtime-physics tests and E2E #206 pass locally. The issue remains open until review, normal merge, release, and fresh released-artifact verification complete.speak-agent commentedon Aug 9, 2026
已在
2026.8.10.1发布(PR #400,合入 commit0006ce6)。链接后校验按 Rule A / Rule B 执行,用的是内置 ELF64-LE 读取器(解析
PT_INTERP、DT_RPATH/RUNPATH、DT_NEEDED、GNU verneed/verdef),不 shell out 探测:GLIBC_*需求不得高于选中 libc 的 export floor。拒绝 host/private 混用,也拒绝两个 private libc 混用。
verdict 与 artifact stat + RuntimeBinding contract hash 一起缓存。缓存的失败仍然是失败:
validated_artifact_snapshot只在每一条已存 verdict 都是 PASS 时才允许工程级快速路径接管,所以「什么都没改,再跑一次就绿了」这条路是堵死的。
mcpp self doctor读的是构建时存下的verdict,不会拿一个可能已经变了的当前宿主重新猜。
回归锁:
tests/unit/test_elf_runtime.cpp(397 行,非 Linux 平台按 typed skip)、tests/e2e/206_runtime_binding_physics.sh,以及本轮新增的tests/e2e/209_runtime_verdict_never_reruns_green.sh—— 它污染一条已存 verdict、不动任何源文件,然后要求下一次
mcpp build仍然失败并打印存档诊断,要求
mcpp self doctor从存档解释,最后要求重建后的产物被重新求值(verdict 是缓存,不是判决,否则第一次真失败就会把项目卡死到只能删
target/)。发布后在隔离 fresh-home 复核:真实项目上
mcpp why runtime报validation: pass (source post_link),覆盖可执行文件与 12 个随产物部署的 X 库。