mcpField
A
antithesis-debug

antithesis-debug

github.com/antithesishq测试与质量302571 次安装1 周前更新
代码仓库

关于 antithesis-debug

antithesis-debug 是用于在 Antithesis 运行或调试会话的指定时刻执行 Bash 脚本的技能。它支持检查运行时状态并调查故障,同时要求使用有效会话和确定的时刻信息。

主要功能

  1. 01在指定时刻执行 Bash
  2. 02检查容器和运行时状态
  3. 03流式查看时间线事件
  4. 04从运行中提取文件
  5. 05从同一时刻复现分支

适用场景

  1. 01调查失败的属性
  2. 02检查指定时刻的容器
  3. 03在日志不足时检查运行状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/antithesishq/antithesis-skills --skill antithesis-debug

安装后在 Claude Code 中输入/antithesis-debug确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
errors.md
gdb.md
kubernetes.md
moments.md
virtual-time.md

详细介绍

Antithesis 调试

技能版本: 2026-10-21 4f8d80b

在运行期间的某个时刻执行 bash 脚本。每次调用都会分支出一个多重宇宙,从同一时刻重复调用会得到相同结果。可以使用当前正在运行的运行实例或活动的 MVD 会话。

何时使用此技能

  • 用户向你提供了 Antithesis 调试会话的运行 ID 或 URL
  • 用户要求你调试或调查失败的属性、Bug 或过去运行中的任何结果
  • 用户要求检查 Antithesis 内的容器文件系统、运行时状态或事件
  • 仅凭日志无法解释故障,因此分诊建议使用此技能

属性失败警告

在运行中的实例上使用 runs exec 执行命令可能会触发该运行实例的断言,从而导致属性失败,看起来与真实 Bug 完全相同。

如果想避免此类误报,请使用调试会话。 如果命令不太可能引发此问题,优先使用当前正在运行的实例,因为它速度快、易于使用,并且消耗的核心时数更少。

前提条件

  • 如果未安装 snouty,请勿继续。安装选项请参阅 https://raw.githubusercontent.com/antithesishq/snouty/refs/heads/main/README.md。
  • 如果 snouty 版本低于 0.8.0(这是 runs exec 稳定的首个版本),请勿继续。使用 snouty --version 查看版本,并使用 snouty update 更新。
  • 必须有来自运行实例或 MVD 会话的会话,才能使用此命令。更多信息请参阅先获取实时会话。
  • 必须通过 snouty 登录 Antithesis 租户。运行 snouty doctor 进行确认。如果尚未登录,请让用户为你登录,或使用 API 密钥。

先获取实时会话

  • exec 需要实时会话。会话可以关联到运行实例或 MVD 会话。在 snouty 中,运行实例和调试会话都显示为运行实例。

  • 运行实例在运行期间以及结束后的一小段时间内会保留会话。完成后几分钟内仍可使用,但几小时后就不行了。

  • 若要查看运行实例是否有活动会话,请使用:

    snouty --json runs show <run> | jq -r '[.status, .sub_status // empty] | join(":") | ascii_downcase'
    

    这会同时打印状态和子状态。in_progress:ready 表示可以对运行实例执行命令。若状态为 in_progress,但子状态不是 ready(例如 in_progress:loading),则会话仍在加载。 snouty runs wait <run> --until ready 会在运行实例就绪可用或已结束时返回。它会打印停止时的状态,因此请确认状态为 in_progress:ready 后再执行命令。

  • 如果用户提供了调试会话 URL,该会话可能已经在运行。请在会话中找到其运行 ID,并根据标题、描述或创建时间进行匹配。runs list 只显示状态,因此请选择一个处于 in_progress 状态的会话,然后确认 runs show 显示其状态为 in_progress:ready:

    snouty --json runs list --launcher debugging \
      | jq -c '{run_id, status, created_at, title: .parameters["antithesis.test_name"],
                source_run: .parameters["antithesis.debugging.run_id"]}'
    

    source_run 是要传递给 --source-run-id 的值。

  • 对于较早的运行实例,请先创建调试会话:

    snouty debug --run-id <run> --input-hash <hash> --vtime <vtime> \
      --title "Counter property failure 2026-10-13"
    
    • 始终传递唯一且便于日后查找的 --title,例如属性名称加日期或工单 ID。这是 snouty runs list 中显示的会话名称。只有当原因无法放入标题时,才添加 --description。--recipients 接受以分号分隔的通知邮箱。
    • 这会返回一个新运行 ID。使用 snouty runs wait <new run ID> --until ready 等待就绪,然后对其执行 exec。
    • 第一个命令要使用 --source-run-id <run>,因为该时刻尚未预热。使用源运行实例时,调用会阻塞,并显示重新预热进度:N%,直到该时刻就绪。
    • 从运行 snouty debug 到首次成功执行 exec,预计需要 2 到 20 分钟:会话加载期间会出现几分钟的 404,然后时刻重新预热;时刻的 vtime 越晚,重新预热所需时间就越长。此后,该时刻已预热,后续针对该时刻执行的命令无需再指定源运行实例。
    • 如果 exec 返回 404 或“Moment not warm”,说明会话仍在加载。请重试。查看获取时刻,找到与用户请求相符的正确 input-hash 和 vtime。

获取某个时刻(输入哈希和 vtime)

input-hash 和 vtime 用于固定要调试的单个时刻。从上下文中提取输入哈希和 vtime,并传给命令。

如果用户没有提供时刻,请查看 references/moments.md,了解在哪里查找。

如果无法从明确的来源确定输入哈希和 vtime,请询问用户,不要猜测。

若要从失败或通过的属性,或从日志行中查找时刻(输入哈希 + vtime),请使用 snouty runs search 查询(参见示例工作流的第 3 步)。

必需输入

  • RUN_ID 是一个正在运行的 run,或调试会话的 run id。

  • INPUT_HASH 和 VTIME 是该 run 中的一个时刻,必须成对取自 snouty runs search 返回的同一事件。

  • INPUT_HASH 通常为负数,例如 -1520695250096255483。请原样传入:snouty 会将其读取为哈希,而不是标志,因此无需添加 --。添加 -- 会将其后的所有标志都变成位置参数,从而导致命令出错。

    snouty runs exec "$RUN_ID" -1520695250096255483 67.7622960046865 'uptime'
    
  • SCRIPT 是要运行的 bash 脚本。将其作为最后一个参数传入,或省略该参数并通过管道传入,例如 < script.sh。

可选标志

  • --timeout DURATION 指定服务器等待脚本退出的时长。需要带单位:90s、5m、1h。纯数字表示秒。默认值为 10m(截至版本 64.0)。重新预热冷时刻的时间不计入其中。
  • --container NAME 在该容器内运行脚本。若不指定,脚本将在主机上运行。
  • --source-run-id ID 指定冷时刻所属的 run。当目标是调试会话时,此处应填写你从中打开该会话的 run,而不是会话 id。启动调试会话后的第一条命令请使用此标志。
  • --source-session-id ID 是 --source-run-id 的会话版本。两者不能同时使用。
  • --events 在脚本运行期间流式输出时间线上的每个事件,而不只是脚本的输出。
  • --json 输出机器可读的 json 格式。
执行提示
  • 在单个容器中运行命令时,优先使用 --container,而不是在脚本内使用 podman exec。

  • --container 需要容器名称,且仅适用于 Docker Compose 测试(参见下文的 Kubernetes 测试)。如果已经运行过 snouty runs search 或 snouty runs logs,请从任意容器日志事件的 source.container 中获取名称。否则,先不带 --container 运行一次,以便在主机上列出容器:

    snouty runs exec "$TARGET" "$HASH" "$VTIME" 'podman ps -a --format "{{.Names}} {{.Status}}"'
    

    在 Docker Compose 测试中,同一个 run 的所有时刻使用相同的名称,因此只需列出一次。

  • --container 仅适用于你所选时刻仍在运行的容器。如果容器此前已崩溃或退出,podman ps -a 会将其显示为 Exited,此时 --container 会失败。请从容器仍在运行的较早时刻执行。使用 snouty runs search 搜索该容器最后几行日志,找到一个时刻。

  • 如果需要跨多个容器获取快照,请勿使用 --container,而应在主机上运行。

  • 要从 run 中获取文件,请将其打印到标准输出并重定向到本地:

    # text
    snouty runs exec "$TARGET" "$HASH" "$VTIME" --container app 'cat /var/log/app.log' > app.log
    
    # binary or a directory: tar + base64, then decode locally
    snouty runs exec "$TARGET" "$HASH" "$VTIME" --container app \
      'tar czf - /data/db | base64' | base64 -d > db.tgz
    
Kubernetes 测试

在 Kubernetes 测试中,--container 不起作用(snouty runs show 中的启动器包含 "Kubernetes" 或 "k8s")。请省略该标志,并阅读 references/kubernetes.md。

从文件运行脚本

  • 对于超过一行的脚本,请将脚本写入文件,并通过重定向传入:

    cat > script.sh <<'EOF'
    echo "host: $(hostname)"
    ps aux
    EOF
    
    snouty runs exec "$RUN_ID" "$INPUT_HASH" "$VTIME" < script.sh
    

    'EOF' 外的引号可避免 $(hostname) 意外在你的计算机上运行。

  • 在多个时刻重复使用同一个脚本。在多个时刻运行同一个文件并比较输出。

  • 将输出保存到以该时刻命名的文件中。

  • 始终将 --events 输出保存到文件中。输出流很长,因此之后请对文件使用 grep:

    snouty runs exec --events $RUN $HASH $VTIME < oracle.sh > out.txt
    grep -E "FAIL|HIT|exit" out.txt
    

选择超时值和计时

  • 根据脚本本身设置 --timeout。冷时刻会先重新预热,这可能需要几分钟(时刻的 vtime 越靠后,耗时越长),但这段时间不计入 --timeout。只有脚本运行缓慢时才提高超时值,例如 --timeout 30m。
  • 超时不代表脚本没有运行。重新运行任何会改变状态的操作前,先搜索此次运行是否已有输出(snouty runs search)。
  • 脚本会推进虚拟时间。快照应尽量简短。在恰当时刻查询一次,而不是反复轮询,因为轮询可能改变你想要观察的时序。
  • 在同一时刻运行相同命令,会得到相同分支。重复运行不会采样新的时序。
  • 在会话中,使用 source 成功执行一次命令后,该时刻会保持预热状态。之后在那里运行命令无需 source,且会很快返回。
  • 会话自身时间线上的较早时刻也已预热,无需重新预热。

重新预热进度

冷时刻会在重新预热期间显示进度。默认情况下,命令会在 stderr 上输出 rewarming moment: N% 行。使用 --json 时,命令会在 stdout 上输出 {"status":"rewarming","percent_complete":N} 帧,然后才输出脚本结果。

  • 百分比上升表示重新预热正在进行。进度上升期间不要重试或取消。
  • 百分比可能会在 0% 停留几分钟,然后跳到接近 100%。停留在 0% 并不表示失败。请让调用继续运行。

完成后取消

运行和调试会话在结束前都会占用核心时长。停止使用调试会话并不会结束它:默认情况下,它仅会在 6 小时后过期。打开的会话一旦不再需要,或近期不再需要,就应立即取消:

snouty runs cancel "$TARGET"
  • 取消会话前请先询问用户。完成后,他们可能还想在另一次调试中继续使用该会话。
  • 取消前,请确认运行或调试会话已彻底完成;如果之后还想运行更多命令,就必须等待新会话完成设置。
  • 除非用户要求,否则不要取消并非由你启动的运行。

工作流示例

1. 前置条件
snouty --version   # 0.8.0 or newer
2. 获取会话
RUN=<run_id>
snouty --json runs show "$RUN" | jq -r '[.status, .sub_status // empty] | join(":") | ascii_downcase'
  • in_progress:ready:直接使用该运行。TARGET="$RUN"。

  • starting,或处于其他子状态的 in_progress:使用 snouty runs wait "$RUN" --until ready 等待,然后仅在输出的状态为 in_progress:ready 时使用该运行。

  • 否则:选择一个时刻(第 3 步),然后在该时刻打开会话并等待。加载期间,如果 exec 返回 404 或 "Moment not warm",请重试。

    snouty debug --run-id "$RUN" --input-hash "$HASH" --vtime "$VTIME" --title "<property> <date>"
    TARGET=<runId from the output>
    snouty runs wait "$TARGET" --until ready
    
3. 选择时刻

使用 snouty runs search 查找时刻,并精确查询你想要的事件。例如,某个属性的失败评估:

snouty --json runs search "$RUN" \
  'filter(ev => ev.antithesis_assert?.hit
    && ev.antithesis_assert.id == "<property name>"
    && !ev.antithesis_assert.condition)' \
  | jq -r '.moment | "\(.input_hash) \(.vtime)"'

要查找通过的评估,请去掉 !。要查找日志行,请使用 contains({output_text: "<error text>"})。要按消息查找断言,请使用 filter(ev => ev.antithesis_assert?.message?.includes("<message text>"))。断言没有 output_text,因此日志行查询无法找到它们。请参阅 references/moments.md。

runs search 默认最多返回 50 条结果。如果需要的结果不止几条,请添加 --limit 999。

4. 执行

启动会话后执行的第一条命令使用 --source-run-id,因为该时刻仍在预热。之后,该时刻已预热,后续命令无需 source,除非你更改时刻。

cat > probe.sh <<'EOF'
hostname
ps aux | head -20
EOF

snouty runs exec "$TARGET" "$HASH" "$VTIME" --source-run-id "$RUN" < probe.sh > out.txt
5. 使用结果

根据输出完成用户的目标,通常是找出错误原因。如果输出无法回答问题,请在更早的时刻再次执行,或从 end moment 行继续向前。

如有必要,请向用户提供时刻、脚本和相关输出,以便他们重新运行。

6. 取消

如果你打开了会话,运行完命令后请询问用户是否要你取消运行。否则,它会继续占用核心时长,直到 6 小时后过期:

snouty runs cancel "$TARGET"

gdb

要使用 gdb 检查进程,请阅读 references/gdb.md。

虚拟时间

在选择某个时刻或探查瞬时事件之前,请先阅读 references/virtual-time.md。

如果较早的时刻尚未预热,请添加 --source-run-id。

常见错误

如果 exec 返回错误,请阅读 references/errors.md。

自我检查

在反馈之前,请根据以下标准检查你的工作:

  • 每项发现都来自实际的 exec 输出,而非推断或假设。
  • 证据链清晰:时刻(输入哈希和虚拟时间)、脚本、脚本返回的内容,以及由此得出的结论。
  • 摘要将输出所显示的内容与解释或建议区分开来。
  • 你已询问用户是否要取消你开启的任何调试会话,或者用户知道该会话仍在运行。

已知问题

  • 在 snouty runs wait --until ready 返回后,exec 仍可能在几分钟内返回 404。请继续重试;会话仍在加载。
  • 执行 snouty runs cancel 后,运行状态可能显示为 completed,而不是 cancelled。取消操作已生效。

评论

支持 Markdown