更正: PATH shim 被否掉的**理由是我没量过的推断**,而且量下来是错的
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:` 头那两次同族:**判据锚在了元文本上**。
This commit is contained in:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user