返回资讯中心
外部精选
软件工程
#开发者实时流

Rewind VM 发布:可回放、可分支的确定性 Linux 虚拟机

来源标题:Rewind VM: deterministic Linux VMs you can scrub, rewind and fork

Rewind VM 让 Nix 构建、测试套件或任意 Linux 命令运行在确定性的 KVM 虚拟机中,相同输入每次产生相同事件,失败时可拖回时间线并从中分叉。v0.10.0 支持 x86_64 Linux,引擎和 CLI 以 MIT 许可证开源,桌面应用个人使用售价 49 美元,可免费试用。

Hacker News 最新sea-gold2026/11/4 · 今天19 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

Rewind VM 在确定性的 KVM 虚拟机中运行 Nix 构建、测试套件或任意 Linux 命令。相同的输入在相同的步骤产生相同的事件,每次都是如此。当它失败时,将时间线拖回到出错的地方,查看周围情况,并从那里分叉。

观看演示(2:24) v0.10.0 · x86_64 Linux 引擎和 CLI 在 MIT 许可证下开源。桌面应用个人使用售价 $49,评估期间免费。

Rewind /nix/store/9x2k…-mylib-0.3.0.drv 运行 #3 · 失败 运行 #2 · 通过 示例数据 运行中的步骤 上一个 下一个 跳转到分歧点分歧 跳转到失败点失败 步骤 虚拟时间 阶段 从此处分叉 在此步骤 构建日志 进程 进程树 · 存活 文件 · 最新优先 在此步骤 附加 gdb 打开 shell 导出运行 清洗器需要 JavaScript 才能运行。

工作负载运行时不记录任何内容。一次运行是其输入的函数,因此它的任何步骤都可以重新计算。

输入——一个 Nix 闭包或任意根文件系统——变成一个只读的 erofs 镜像,直接映射到虚拟机的内存中。一个小型 Linux 内核启动并运行你的命令。

在标准 KVM 上使用一个 vCPU,因此虚拟机中的代码运行在真实 CPU 上。虚拟机的内核携带一个小型 Rewind 平台:中断仅在虚拟机将控制权交给 Rewind 时到达,时间仅在此时推进,时间戳计数器和硬件 RNG 被隐藏。一个步骤就是其中一次交接。

每四分之一秒的墙钟时间,Rewind 使用 KVM 的脏页日志对机器进行快照。页面进入一个内容寻址存储(BLAKE3、zstd),因此一个被关键帧、运行和分叉共享的页面只存储一次。

要到达某个步骤,Rewind 恢复该步骤或之前的最新关键帧并向前运行。相同的输入,在相同的步骤产生相同的事件。

真实的应用程序,针对教程所追踪的那个 bug。 1 2 3 4 5 6 时间线 整个运行过程,以及它与通过的那次运行在何处分开。 构建日志 构建打印的内容,直到播放头。 进程和文件 当时在运行什么,以及写入了什么。 步骤的事件 这里是 SIGSEGV,以及两次运行在何处分开。 从此处分叉 在新的调度下从此步骤重新运行。 每次运行 构建的所有运行和分叉,以树形展示。 两次运行从分开处并排展示,差异以琥珀色标出。 每个步骤中哪个线程持有 CPU,在两次运行中都是如此。 从一个步骤运行 8 到 64 种调度,并统计它们如何结束。 在运行的任意步骤使用 gdb,这里停在一个监视点上。 播放头处线程所在的源代码行,及其调用栈。 构建的每次运行和分叉,以树形展示。 虚拟机内核在构建日志中的消息,这里是它的段错误报告。 $ rewind run --root mylib.tar --cwd /src -- make check 根目录可以是一个目录、一个 erofs 镜像,或一个 tarball,例如 docker export 写出的那种。虚拟机将其挂载在一个可写覆盖层下,命令写入的任何内容都不会到达你的磁盘。 $ rewind nix .#mylib $ rewind check .#mylib 固定的输入、无网络、固定路径。将 Rewind 指向一个 flake 属性,使构建确定化的大部分工作就已经完成了。 前两个追踪一个真实的 bug——一个小型 C 线程池中的关闭竞态——从安装到修复;第三个说明什么是正确的运行;第四个到达两行代码之间的竞态;第五个找出构建为何无法复现;第六个是其余的工具。其中的每个终端记录都是真实输出。 用 Nix 安装,让 rewind check 找出使一个 derivation 的测试崩溃的交错,然后重放它、分叉它并检查修复。 同一个 bug,来自一个没有 Nix 的 Docker 镜像:导出文件系统,找到失败的调度,并精确重放崩溃。 在第一次运行就能捕获 bug 的属性、来自程序内部的断言,以及改变其随机性和调度的种子。 一个读和写之间没有系统调用的竞态,任何调度都无法到达,直到 SDK 中的一行在那里放了一个切换点。 在多个种子和目录顺序下构建一个 derivation,看看哪些文件不同,并让 rewind blame 指出写入这些字节的程序。 简短配方:哪个线程持有 CPU、监视点、崩溃时内核那一侧的情况、虚拟机内部的工具、更多 CPU、统计从一个步骤开始失败的调度数,以及分享一次失败的运行。 Rewind VM 在 Nix 自己的测试套件和 devenv 上的应用。其中的每个终端记录都是真实输出。 Rewind 首次运行 Nix 的测试套件时,在 gc-closure.sh 中遇到了一个 SIGPIPE 偶发问题:在 pipefail 下管道到 head -n1。已报告并通过 here-string 在上游修复。 Nix master 中一个已知的 SQLite schema 迁移挂起问题,在 Rewind 中复现,并通过虚拟机内的 gdb 定位到 SQLITE_BUSY_SNAPSHOT。 一个已知的 devenv bug,会丢弃任务的最后几行,在 Rewind 中复现,并通过 gdb 追踪到 tokio::select! 在缓冲行之前获取了子进程的退出。 适用于带 KVM 的 x86_64 Linux。引擎和 CLI 在 GitHub 上开源,桌面应用在评估期间可免费下载和使用。 可以直接从 flake 运行,或将两者都安装到你的 profile 中: $ nix run github:fzakaria/rewindvm -- pmu status $ nix run github:fzakaria/rewindvm#app $ nix profile install github:fzakaria/rewindvm github:fzakaria/rewindvm#app 在 NixOS 上,将 flake 添加为输入并启用其模块: inputs.rewind.url = "github:fzakaria/rewindvm";

在你的配置中,导入 inputs.rewind.nixosModules.default;

它还会将 rewindvm.cachix.org 添加到 Nix 的 substituters

programs.rewind.enable = true; programs.rewind.app.enable = true;

仅限 AMD:使分支计数器在每次启动时精确

programs.rewind.amdBranchCounterWorkaround = true; 不使用 Nix $ curl -fsSL https://rewindvm.dev/install | sh 或者自己从最新发布中获取 tarball:

rewind 命令,包含虚拟机的内核

$ curl -L https://github.com/fzakaria/rewindvm/releases/latest/download/rewind-x86_64-linux.tar.gz | tar xz

桌面应用

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →