From 8903ce5aa41873e4f3f7cdfcc355260c3f31906e Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 21 Sep 2026 05:14:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=AD=A3:=20PATH=20shim=20=E8=A2=AB?= =?UTF-8?q?=E5=90=A6=E6=8E=89=E7=9A=84**=E7=90=86=E7=94=B1=E6=98=AF?= =?UTF-8?q?=E6=88=91=E6=B2=A1=E9=87=8F=E8=BF=87=E7=9A=84=E6=8E=A8=E6=96=AD?= =?UTF-8?q?**=EF=BC=8C=E8=80=8C=E4=B8=94=E9=87=8F=E4=B8=8B=E6=9D=A5?= =?UTF-8?q?=E6=98=AF=E9=94=99=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pi 建议用 PATH shim 覆盖 `del()` 的失败路径("假 rm 放 PATH 前面,只对窗口外那一个目标失败")。 我 09-14 否掉了它,并在两处注释里写下理由:「`in_use` 会把命令行里含该路径的进程判成在用」。 **这个理由我没验证过,而实测它不成立。** ## 实测 基线 ⇒ 通过 22 / 失败 0 shim(全量 rm) ⇒ 通过 16 / 失败 9(另 6 项红) shim(只该目标) ⇒ 通过 16 / 失败 9 ← 与全量**完全一样** `正在被使用` 在自检全过程中出现 **0** 次 ⇒ `in_use` 根本没触发,它不是原因。 ## 真因:夹具与"窗口外那一个"撞了同一个时间戳 自检夹具 `mktree` 建的就是 `$T/agentmail-gateway.bak-20260101-000000`, 而"窗口外该删的那一个"**也是它**(`:210/:221` 断言它被删)。 于是任何"对 `20260101-000000` 失败"的 shim,会连**夹具自己的清理**一起打掉 —— 红的六条全是【干净样本】("窗口外没了、窗口内还在"等), 即测到的是"夹具坏了",不是"删除失败被报出来了"。 ⇒ 让 `rm` 失败必须走**注入点**:`$RM` 的作用域是"del() 这一次调用", PATH shim 的作用域是**整个进程**,而自检夹具活在同一个进程里,躲不开。 **结论(用 `$RM`)当初就是对的,理由说错了** —— 与 pi 这轮纠正我的形状完全相同。 ## 顺带一条计数纪律(我自己又踩了) 我 `grep -c '失败'` 那份日志得到"失败 1",其实那 1 行是 `通过 坏样本(rm 删不动):必须打出那句点名失败的 [FAIL]` —— **"失败"出现在一条 通过的样本名里**。按行首标记精数 ⇒ **22/22 全绿**。 与 `grep -c 用例名` 数出假数、`# Subtest:` 头那两次同族:**判据锚在了元文本上**。 --- deploy/prune-deploy-artifacts.sh | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/deploy/prune-deploy-artifacts.sh b/deploy/prune-deploy-artifacts.sh index 23cd443..936665f 100755 --- a/deploy/prune-deploy-artifacts.sh +++ b/deploy/prune-deploy-artifacts.sh @@ -93,8 +93,25 @@ del() { # **只在成功后才累加**,收尾汇总不再虚报。 if [ "$APPLY" = "1" ]; then # `$RM` 只是为了**让自检能喂一个"删不动"的失败**(见 --self-check 那一段): - # 默认就是 `rm`,生产行为逐字不变。不用 PATH shim 是因为 `in_use` 会把 - # 命令行里含该路径的进程判成"在用",而自检必须把路径写在命令行上。 + # 默认就是 `rm`,生产行为逐字不变。 + # + # ★ 为什么**不**用 PATH shim(pi 2026-09-14 建议过,我实测后否掉,2026-09-21 补正) + # + # 我原先在这里写的原因是"`in_use` 会把命令行里含该路径的进程判成在用" —— + # **那是我没量过的推断,而且量下来是错的**:自检跑完 `正在被使用` 出现 **0** 次, + # `in_use` 根本没触发。真正的失败原因是**夹具与该路径撞了同一个时间戳**: + # + # 自检夹具建的就是 `$T/agentmail-gateway.bak-20260101-000000`(`mktree`), + # 而「窗口外那一个」恰恰也是它 —— 于是任何"对 `20260101-000000` 失败"的 shim + # 会连**夹具自己的清理**一起打掉。实测(两种 shim 都试过): + # 基线 ⇒ 通过 22 / 失败 1 + # shim(全 rm) ⇒ 通过 16 / 失败 9 + # shim(只该目标)⇒ 通过 16 / 失败 9 ← 与全量 shim **一样**,因为目标就是夹具 + # 红的六条还都是【干净样本】("窗口外没了、窗口内还在"等)—— 即 shim 把 + # **本应绿的样本**打红,测到的是"夹具坏了"而不是"删除失败被报出来了"。 + # + # ⇒ 让 `rm` 失败这件事,只有**注入点**能精确限定在"del() 这一次调用"上; + # PATH shim 的作用域是**整个进程**,而自检夹具活在同一个进程里,躲不开。 if ! "$RM" -rf "$path"; then printf ' [FAIL] 删不掉:%s(权限/只读挂载/immutable?)\n' "$path" >&2 @@ -244,8 +261,10 @@ if [ "${1:-}" = "--self-check" ]; then # 早先我以为覆盖不了它:本机以 root 跑,权限拦不住 `rm`;`unshare -r` 被拒 # (`/proc/self/uid_map: Permission denied`);tmpfs 无 `chattr +i`。 # pi 指出第三条路是**让 rm 自己失败**,而不是去改机器的权限 —— 于是有了 `$RM` 覆盖点。 - # (不用 PATH shim:`in_use` 会把命令行里含该路径的进程判成"在用", - # 而自检必须把路径写在命令行上。) + # ★ 但"让 rm 失败"必须走**注入点**,不能走 PATH shim:shim 的作用域是整个进程, + # 而下面这些夹具(`mktree`)活在同一个进程里、且用的**就是** `20260101-000000` + # 这个时间戳 ⇒ shim 会把夹具自己的清理一起打掉,红的全是【干净样本】。 + # 实测:基线 22 通过/1 失败;两种 shim 都退化成 16 通过/9 失败(详见 `del()` 里的注释)。 T2="$(mkdtree_fail)" cat > "$T2/fake-rm" <<'FAKERM' #!/usr/bin/env bash