Wax:录下程序的运行,改完代码再重放一遍
文章摘要
Wax 是一门尚处预览阶段的可嵌入编程语言,作者 Matt(HN 用户 weichx)把它的口号定为「过去是可编程的」。它要解决的问题很具体:让程序历史上的任意一个瞬间,都能在任意机器上被原样重现。
这听上去像是常见的时间旅行调试(time travel debugging),但 Wax 的定位要更激进一些。它的设计目标是在生产环境里持续录制自身的执行,并把性能和存储开销压到低于实用门槛之下——也就是说,录制不是调试时才打开的开关,而是程序默认就在做的事。录下来的不是视频,而是一份包含可恢复的程序状态、完整输入序列(input tape)以及重建每一帧所需上下文的产物,因此可以在任何现代操作系统和 CPU 上逐字节一致地重放。
拿到一份录制之后,能做的事远不止「再看一遍」:
- 查询过去:针对任意已恢复的帧写全新的代码去读取内部状态。官网展示的命令行工具
waxdbg支持类型安全的 query 函数,比如把某个从来没有被打过日志的字段在几千帧区间内画成曲线,或者用find --where "NearbyEnemyCount() >= 4"找出所有满足某个条件的时间区间。 - 追踪写入:列出某个字段在某一帧被谁改过,带完整调用栈和源码行号。
- 双向调试:向前单步,也能向后单步。
- 事后计时:查询你当时根本没埋点的帧耗时、分配次数等遥测数据。
- 改规则再跑:修改源码后在同一份录制上重放,看历史如何改写。
官网的招牌演示是一个跑在浏览器里的 DOOM。你先真实地玩上 30 秒,Wax 录下这段过程,然后网页会用三条「事后才写出来的」规则重放同一段输入:强制只能用等离子枪、每开一枪扣一点血、所有敌人只有 1 点血。由于 DOOM 是软件渲染,你能直接看着过去在眼前被改写。作者特意说明,选 DOOM 只是因为它人人都熟、节奏快、画面直观,这些能力本身和游戏无关。
作者的动机来自他长期的游戏开发生涯:bug 报告往往只有一张截图、一段调用栈或者一句「它坏了」,而复现需要凑齐对方的硬件、驱动、构建配置。他想要的是「让 bug 报告本身就是那个 bug」——把用户当时所处的程序状态原封不动搬回自己的机器。他还提到一个当下很应景的用途:录制可以被编码代理直接读取,让 AI 基于实际发生过的事推理,而不是仅凭源码和日志猜测。
HN 评论精华
需要如实说明:这条提交在 HN 上几乎没有引起讨论。帖子只有 5 分,整个评论树里只有一条内容——就是作者 weichx 自己发的 Show HN 自述,没有任何第三方回复、质疑或对比。上面的文章摘要因此主要基于官网内容和作者这段自述撰写。
作者自述中值得单独拎出来的几点,也是这个项目真正想区别于既有方案(rr、Replay.io、各类 record-and-replay 调试器)的地方:
- 录制要便宜到能常开。他强调开销「低到在生产环境录制是可行的」,这是与传统时间旅行调试最大的分野——后者通常只在本地开发时启用。
- 重放不是只读的。可以改代码之后在同一段历史上重跑,而不只是回看。
- 堆可以当数据库查。录制里的状态支持结构化查询,去捞那些「当初根本没想到要记录」的信息。
- 跨平台逐字节一致。录制在任意现代 OS / CPU 上重放结果完全相同。
- 面向 AI 代理。作者把「录制可被编码代理直接检查」列为一等特性。
由于缺少社区反馈,这个项目最关键的问题——生产环境录制的真实开销究竟有多大、需要用 Wax 这门新语言重写多少代码才能受益——目前还没有来自第三方的验证。