技术文章 Fzakaria Blog 2026/11/09
文章从构建可信性出发,讨论若每个 Nix 构建都实现比特级可复现,将对输入寻址与内容寻址模型产生什么影响。作者指出 Nix 默认通过哈希输入获得可重复性,但仍需信任缓存;内容寻址虽按输出内容命名,却因构建器不纯可产生多个输出。作者用确定性虚拟机 Rewind 捕获时间、随机种子、调度等隐式输入,并通过 inRewind 包装 derivation,使普通构建在 --check 下通过,且两个内容寻址 store 得到相同路径。结论是比特级可复现会让两种模型趋同,带来跨机器缓存命中和 early cutoff 收益。边界在于 Rewind/KVM、CPU 厂商和版本都成为新输入,固定输出 derivation 也因无网络被排除。
推荐收录,因为文章不仅有概念推演,还用 greet/hello 示例展示 --check 失败到 Rewind 下通过、两个 store 路径一致的直接证据。适合 Nix、构建系统与可复现性方向读者,可迁移的是把构建环境隐式输入显式化的思路。主要风险是 Rewind 依赖 KVM、CPU 厂商与版本,且固定输出构建不适用。
工程实践 Fzakaria Blog 2026/11/07
文章讨论 PGO 在包管理器中因训练运行不确定而难以复现的问题:同一源码经插桩、训练、再编译后,线程调度等因素会让 profile 计数不同,进而生成不同二进制。作者以 Nix 与 Guix 禁用 Python/GCC 的 PGO 构建为背景,提出用确定性虚拟机 Rewind 固定启动时钟、随机种子、线程调度和 CPU 模型,把构建拆成插桩编译、VM 内训练、最终编译三个 derivation,并校验 CPU vendor。文中用一个多线程 C 示例展示 profile 每次变化、不同调度导致 compress 被误判为死代码,最终通过 nix-build --check 验证 profile 和二进制可逐位复现。边界是训练运行需绑定 AMD/Intel vendor、依赖 KVM 与特定 system-features,且训练负载选择仍带艺术性,示例较简单。
推荐收录:文章不是泛泛谈 PGO,而是给出可执行的 Nix derivation,并用 nix-build --check 证明 profile 和最终二进制逐位一致;同时用多线程示例说明训练运行为何不确定、调度如何影响 profile。适合构建系统、包管理、编译器优化和可复现基础设施的读者,可迁移的要点是把非确定性训练隔离到可控 VM 中,并将 vendor、seed、schedule 等作为 derivation 输入。主要风险是方案绑定 CPU vendor 和 KVM,示例规模有限,真实程序的训练负载选择仍需额外判断。
技术文章 Fzakaria Blog 2026/11/06
文章指出 Nix、Bazel 与 buck2 底层都采用内容寻址的“内涵模型”,并用 C 示例说明失效传播。Nix 默认输入寻址会因上游注释改动重建 greet 和 hello;启用实验性 CA derivations 后仅重建 greet,hello 复用旧结果。Bazel/buck2 默认以命令和输入摘要作为 action key,靠 action cache 与 early cutoff 避免无关重编译。作者将 resolved derivation、realisation、store path 映射到 Action、action cache 与 CAS blob,显示 Nix 与 REAPI 概念一致。不足是 Nix CA 仍属实验特性,动态 derivation 未稳定,文章偏概念验证而非性能基准。
推荐收录:文章用可复现的 C 编译示例和映射表,直接比较 Nix CA derivations 与 Bazel/buck2 action cache,证据具体,能解释 early cutoff 与重建粒度。适合构建系统、Monorepo 基础设施和缓存设计读者,可迁移到依赖失效分析与内容寻址缓存。需注意 Nix CA 仍是实验特性,且文章不是性能基准,读者应具备一定构建系统背景。
技术文章 Fzakaria Blog 2026/11/05
文章介绍 Rewind 如何通过确定性重放实现“反向调试”:它先完整记录一次程序(含内核)执行,之后恢复最近检查点并向前重放到目标步,同时用硬件观察点捕获该值的读写,从而得到最后一次写入或完整读写历史。作者用两个柜员并发存款丢失更新的例子演示 rewind blame 与 --reads 如何定位陈旧读取和覆盖写,并说明 rewind gdb 可用 watchpoint 加 reverse-continue 反向往回走。核心结论是“后退”可由从前一检查点再次快进实现,依赖完全确定性回放,且单步窗口可能包含大量指令、需要多次重放,示例本身较简单,真实缺陷的修复仍更复杂。
推荐收录:文章给出了“反向调试靠向前重放”的具体实现路径——检查点恢复、确定性重放和观察点捕获读写,并用丢失存款的并发例子展示 rewind blame --reads 的定位过程。适合系统、运行时、调试器与开发工具方向的工程师阅读,其中确定性回放和值历史追踪方法可迁移到自研调试或诊断工具;需注意内容围绕特定工具,缺少性能开销与大规模验证数据。
技术文章 Fzakaria Blog 2026/11/03
文章围绕“bug 并不稀有,触发它的调度才稀有”展开:先复盘 AWS RDS 工作流中 worker 长暂停、心跳失效、任务被重新分配后旧 worker 恢复执行的事故,说明需要幂等和调度测试。随后用两个线程对 counter++ 的例子枚举 6 个步骤的 20 种交错,指出仅 2 种得到正确结果,并在空闲/繁忙笔记本与 Rewind 确定性虚拟机之间对比实际覆盖的调度数和丢更新次数。实验显示 Rewind 在 barrier 版本可达全部 20 种顺序,丢更新率显著高于宿主机;文章还介绍用 --stall-max/--stall-min 探索长暂停等更稀有调度。其价值在于把调度视为测试变量,但结论依赖特定工具和较小实验,不能替代形式化验证或证明无竞态。
推荐收录。文章给出了可直接验证的证据链:AWS 真实事故、20 种交错的理论枚举,以及空闲/繁忙宿主机与 Rewind 的 10,000 次运行对比表,说明调度扰动确实能暴露常规测试漏掉的竞态。它适合做并发测试、稳定性、运行时或开发者工具的人阅读,其中“把调度当测试变量、用幂等兜底、用 stall 参数探索长暂停”可迁移到类似系统;风险是案例规模较小且带有工具推广色彩,不能据此推断所有 bug 都来自调度。
工程实践 Fzakaria Blog 2026/11/01
文章围绕确定性虚拟机 Rewind 如何表示“时间”展开,指出宿主墙钟受负载、中断和缓存影响,无法在重放时保持确定性。作者比较两种时钟:exit time 仅在系统调用等退出点推进,导致计算被视为瞬时;counter time 则按条件分支退休数计步,依据是同一程序的指令流可复现。通过 perf 实验,作者发现指令计数器会因中断和缺页而多计,条件分支计数器则基本不受外部中断影响,但 AMD Zen 的 SpecLockMap 会造成少量过计。文章结论是分支计数能较好近似 guest 内时间,可复现超时与竞态,但仍只是近似,且具体开销常量和平台行为需校准。
推荐收录。文章不是泛泛介绍确定性调试,而是用 exit time/counter time 对照、perf 数据和中断计数解释为何条件分支计数器更适合作为可重放时间代理,并给出 AMD SpecLockMap 这类平台细节。适合虚拟机、运行时、调试器和可靠性测试开发者参考,其时间建模与验证方法可迁移到确定性重放和竞态/超时复现场景;局限是结论依赖 Rewind 实现与特定硬件。
工程实践 Fzakaria Blog 2026/10/28
文章围绕作者自研的确定性虚拟机 Rewind VM,讨论“定位到失败步骤之后,读懂代码仍是调试中最难的部分”。Rewind check 会在多种线程调度下重放测试,把失败缩到单步;作者以 git notes 并发添加导致一条 note 丢失为例,展示 rewind diff、blame、where 如何定位到 ref 文件、读写时序和 notes-utils.c:64 的 read-modify-write 竞争。文章进一步主张把确定性运行轨迹交给 LLM 或 Agent 解析,以缩小上下文并辅助给出修复,但也承认例子较小、依赖调试符号和工具链,LLM 仍有随机性。
推荐收录:文章用 git notes 竞争这一真实案例串起 diff、blame、where 三个命令,并明确给出从失败步骤到具体源码行的证据链,不是泛泛介绍工具。对调试并发或不确定性缺陷、构建可复现性和探索 LLM 辅助调试的工程师有迁移价值;需注意案例依赖 Rewind 与 Nix 环境,且作者立场带有工具推广色彩。
技术文章 Fzakaria Blog 2026/10/24
文章解释 Rewind VM 如何把非确定性系统变成可复现的确定性虚拟机。作者先指出 CPU 本身是确定的,非确定性来自时钟、中断、随机数和多核竞争等外部影响,然后说明 Rewind 通过 KVM 运行客户机,并让打补丁的 Linux 内核在需要时间、定时器或空闲时主动触发 VM exit,由 rewind-vmm 接管时间、注入中断并记录事件;每个 exit 称为一个 step。文中用一个读取时钟、取随机数、sleep 并打印的程序逐步展示系统调用如何落到虚拟时钟和种子随机数上,最终同一 seed 得到相同输出和 432 步,换 seed 则结果改变。文章还提到单 vCPU、erofs 输入镜像和隐藏硬件计数器等设计,但方案依赖定制内核与 init,适用范围限于受控 guest 环境。
推荐收录,因为它没有停留在“确定性 VM”的概念宣传,而是沿着一个 C 程序的系统调用路径,给出 VM exit 分步、monitor 伪代码、同一 seed 的实机输出和 432 步计数等直接证据。适合操作系统、虚拟化、可复现构建和调试工具方向的读者,用于理解如何用协作式退出、虚拟时钟和种子随机性控制外部输入;需注意该方案依赖定制 Linux 内核和 rewind-init,并非对任意二进制透明。
技术文章 Fzakaria Blog 2026/10/23
文章介绍 Rewind VM 新增的 `rewind blame` 命令:当两次构建输出不一致时,它能定位第一个差异字节由哪个程序、在哪个步骤写入。作者用 Python 集合迭代顺序和目录项顺序导致 pkg-config/插件索引变化的两个例子,串联 `rewind check`、`rewind diff` 与 `rewind blame` 的排查流程。其关键在于运行期记录程序启停、文件打开/重命名以及客户机内核的 write/open 记录,因此无需完整重放即可沿写入链回溯,仅在读取文件内容时重放。文章还说明可通过变化随机种子、线程调度和目录顺序暴露非确定性,并用 `sorted()` 修复。适用边界是依赖 Rewind VM 和 Nix 生态,输出较长且需要理解其溯源模型,非该环境不能直接套用。
推荐收录:文章给出了 `rewind blame` 的完整证据链——从差异字节、首个写入程序到客户机内核 write/open 记录,并用 Python 集合顺序和目录项顺序两个案例验证根因。适合维护构建系统、Nix 包或排查不可复现问题的工程师,其“差异字节→写入链→首个写入者”的定位方法可迁移到其他构建诊断工具。主要局限是强依赖 Rewind VM 的运行时记录,跨生态适用性需读者自行判断。
个人心得 Fzakaria Blog 2026/10/20
文章从 nixpkgs 手册中 Ruby 平台专用 gem 的长期缺口切入,指出对应 PR 从 2019 年悬置到 2026 年仍未合并,说明软件栈中大量“缝隙”因修复成本过高而被长期容忍。作者认为 LLM 显著降低了补齐这类缺口的成本:原本需要数天的手工工作,可压缩为一下午甚至一小时的 agent 协作,并以其为 Nix/Ruby Bundler lockfile 编写的 gemlock.nix 为例。文章强调 Nix 的可复现环境可作为 AI 生成代码的验证测试床,同时提醒 AI 代码可能产生 slop,需要把“指挥与审阅”当作可训练技能。结论是软件经济性已变化,团队可以更高标准地要求软件栈正确性;但文中主要是观点与单例经验,未展开实现细节、评测方法和适用范围。
推荐收录,因为它用 nixpkgs 中一个悬置多年的 Ruby gem 缺口和作者一小时内完成 gemlock.nix 的具体对照,说明 LLM 正在改变补齐软件栈长尾缺口的成本结构。适合 Nix/包管理维护者、AI 辅助开发实践者及关注工程效率的读者,其中“用可复现环境验证 AI 生成代码”的做法可迁移。需要注意的是全文仍是观点性单例,缺少代码、测试与规模评估,读者不宜把一小时案例直接外推为普遍结论。
工程实践 Fzakaria Blog 2026/10/17
文章讨论如何用可重定位二进制打破 Nix 包固定在 /nix/store 的限制,使 Nix 与 Bazel/buck2 共享存储。作者将 RUNPATH 改为基于 $ORIGIN 的相对路径,并借助 Linux 7.3 的 binfmt_misc eBPF 处理器在 PT_INTERP 中展开 $ORIGIN,让 store 路径从绝对地址变成可放置布局。文中给出 buck2 规则与远程执行原型:worker 无需 gcc,输出以 buck2 digest 作为 Nix store path,经 REAPI CAS 回传,实现同字节同名。文章还列出 nixpkgs 相对 RUNPATH、相对 cc-wrapper 与 Nix 内容寻址哈希等落地条件;但仍是早期原型,依赖 Linux 7.3 和较大生态改动。
推荐收录,因为文章不是空谈 Nix 与 Bazel/buck2 集成,而是给出可运行的远程执行原型、$ORIGIN/PT_INTERP 机制和 digest 回流路径,并明确列出所需内核与 nixpkgs 改动。对做包管理、构建系统、远程执行或 Linux 加载器的人有较高可迁移价值;风险是方案仍处早期,强依赖 Linux 7.3 和跨生态改造。
技术文章 Fzakaria Blog 2026/10/14
文章介绍确定性虚拟机 Rewind VM 将属性测试思想引入线程调度搜索:它记录程序每一步(含线程调度)以精确重放,并把「运行是否真为 bug」转化为可声明的属性。作者提出三类属性——always(所有运行都必须成立的安全属性)、sometimes(至少一次运行成立的可达性属性)、never/unreachable(任何运行都不得命中),并配合基于 trace 的内置属性(no-crash、no-orphans、single-writer、atomic-replace、junit 等)与 SDK 断言。以两个柜员无锁并发存款的 Java 例子演示:初始测试全部通过,但 sometimes 指出从未出现并发交错,随后在默认 64 个调度中找到丢失存款的竞态,加锁后 sometimes 在 42/65 次运行中成立从而验证修复。SDK 覆盖 C/C++、Rust、Go、Python、Java、Shell 等语言。局限是依赖 Rewind VM 环境、JVM 步数庞大,且 sometimes 的语义设计需要谨慎思考。
推荐收录:文章把属性测试(always/sometimes/never)迁移到确定性的线程调度搜索上,用真实的 Java 竞态例子完整展示「测试通过≠正确」、定位失败调度、加锁后用 sometimes 验证修复的证据链。对做并发测试、flaky test 排查、可靠性工程的读者有直接可迁移的方法价值;主要局限是强依赖 Rewind VM 环境。
工程实践 Fzakaria Blog 2026/10/12
文章介绍 jinx:一个把 Nix 转译成 TypeScript 的工具,并把整个 nixpkgs 编译成 TypeScript 模块。作者认为 Nix 的核心价值不在语言,而在 store 模型与 nixpkgs 二十年积累;转译能让 TypeScript 生态复用这些成果。jinx 保留惰性求值,用 thunk 包装表达式,生成代码可读并带 source map,可在 Node 或浏览器中求值。验证方面,作者对 nixpkgs 在 x86_64-linux、aarch64-linux、aarch64-darwin 三平台与 nix-eval-jobs 对比 231,777 个属性,229,063 个 drvPath 完全一致,2,714 个双方均失败,差异和单边失败均为零。工具支持编辑器 LSP、断点、REPL、node:test 以及用 TypeScript 写包;不足是求值比 Nix 慢约 3-5 倍、内存高约 2-4 倍,且求值不写 /nix/store,更适合探索与教学而非性能敏感生产。
推荐收录:文章给出把 nixpkgs 转译为 TypeScript 的完整工程证据,并以 231,777 个属性跨三平台对比 drvPath,实现零差异,验证扎实。适合研究 Nix store 模型、转译器/运行时可复现性、开发者工具或浏览器求值的读者;其 source map、LSP、基准与跨平台验证方法可迁移到其他语言生态。主要风险是性能与内存开销明显,且工具维护性需结合 AI 参与实现的具体情况自行评估。
工程实践 Fzakaria Blog 2026/10/07
文章介绍 Rewind VM:一个把 Nix 构建的每次运行都视为输入纯函数的确定性虚拟机,用于发现、复现并定位 Nix 构建中的竞态条件。作者以“两个柜员操作同一账户”的经典丢失更新为例,展示 rewind check 如何在扰动调度下把首次失败精确缩小到某一步,并用 rewind where、rewind gdb、rewind shell、Compare 与 Check from here 等能力还原“谁在何时占用 CPU”。文章核心论点是:调试器所需的程序输入、源码、调试符号以及让他人本地复现的机制,恰好由 Nix 派生(derivation)和 debuginfod 免费提供,作者只是在其上补了少量逻辑。结论是只要以 Nix 派生这类 hermetic 单元为起点,就能以很小成本获得调试器的大部分能力。边界在于该能力高度依赖 Nix 生态与确定性重放,且单 CPU 模拟需要额外扰动调度的检查手段。
推荐收录,因为文章不只描述工具功能,还给出具体命令、失败步骤编号、16 个扰动调度全部失败等可验证证据,完整呈现了从可复现输入到竞态定位的工程分析链路。适合从事构建系统、并发调试、可复现性与 Linux 系统工具开发的读者,其“把可复现性当作调试基础设施”的思路可迁移到其他 hermetic 构建或 VM 场景。
工具笔记 Fzakaria Blog 2026/10/04
文章指出 Nix 构建虽由输入决定产物,但线程调度仍是隐藏输入,导致 CI 上难以复现的 flaky 测试与构建。作者构建 Rewind VM,在 KVM 虚拟机中运行 Nix 构建、测试或命令,把时钟、中断和调度等外部事件记录为可回放输入,支持确定性回放、按步骤检查和在不同交错下 fork。文中以哲学家就餐死锁为例,展示 rewind check 如何扰动调度、缩小失败窗口,并用 shell/gdb 检查锁持有者,再通过导出/导入/回放在另一台机器复现失败。该工具还发现 Nix、nixd、jujutsu 等项目的真实并发缺陷;限制是单 vCPU、无网络、仅 KVM/x86_64 Linux,且回放依赖 CPU 厂商。
推荐收录:文章给出了 Rewind VM 的完整动机、KVM 确定性回放机制与可操作命令,并以哲学家就餐死锁演示调度扰动、失败窗口缩小和 gdb 检查,还列出 Nix、nixd、jujutsu 的真实修复。适合调试 CI flaky 测试、并发缺陷、Nix 构建和可复现系统的工程师,可迁移价值高;但方案仅支持单 vCPU、无网络、x86_64 Linux/KVM,且回放受 CPU 厂商限制。
工具笔记 Fzakaria Blog 2026/09/28
文章讨论作者如何在使用 AI 编码代理时,避免自己和代理产出“AI 腔”文本。他把 home-manager 的 agent-settings.nix 声明式生成 ~/.claude/CLAUDE.md 与 AGENTS.md,汇总维基百科和 Simon Willison 的 AI 写作特征,禁用 delve、tapestry 等词及“不是 X 而是 Y”等句式。发现提示无法稳定约束后,他复用代理自己写出的 tools/check-prose.py,在 CI 中以确定性检查拦截禁用词、短语和破折号,认为可验证、可复现的检查优于上下文提示。作者还统计历年博文,发现 2025-2026 年破折号与违禁词明显上升,并引用 Goodhart 定律提醒该指标本身会失效。内容偏个人实践与反思,缺少系统评测和推广验证。
推荐收录,因为它给出可迁移的具体做法:用可运行、可验证的 CI 脚本来约束 AI 生成代码与文档的写作风格,而不是依赖易被忽略的提示词,并用 Goodhart 定律诚实地指出该指标的局限。适合在仓库中大量使用编码代理、关心代码与文档风格的工程读者参考;风险是内容以个人实践为主,样本和评测有限。
工程实践 Fzakaria Blog 2026/09/25
文章介绍 omnibin:一个基于 FUSE 的文件系统,把 nixpkgs 历史中几乎全部二进制放到 $PATH 上,实现“无需安装、无需构建”的按需包访问。其核心是利用 cache.nixos.org 上 Hydra 生成的 .ls 元数据作为索引,再结合 nixpkgs-multiverse 将 (attribute, version) 解析到已构建的 store path,并在首次读取时从缓存拉取 NAR 解包。作者展示了 5 万多个顶层二进制、88 万级二进制树、版本化命令(如 python3@3.6.2)以及 Docker/NixOS 集成方式。为避免 FUSE 全树 stat 过慢,工具只列出每个二进制的最新版本,并提供 index.db 和 omnibin CLI 查询。代价是首次访问需下载解包(示例约 2.7 秒),后续因 store 已存在而瞬时返回。
推荐收录。文章不是泛泛介绍 Nix,而是给出 omnibin 的完整机制:利用 Hydra .ls 索引和 nixpkgs-multiverse 做版本解析,再用 FUSE 懒加载 NAR,并讨论了 ls 性能、首次访问延迟和查询接口等真实约束。对研究包管理、FUSE/文件系统、开发环境与可复现构建的读者有直接迁移价值。
技术文章 Fzakaria Blog 2026/09/21
文章围绕 Nix 动态 derivations,用 applicative 与 monadic 类比说明传统构建图必须预先可知,而动态 derivations 把 bind 从求值器下移到调度器,使构建中可继续生成新 .drv。作者以掷骰子为例:step 掷 d6,非 6 则生成 passthrough 并递归 depth+1,6 则终止并输出深度,涉及 builtins.outputOf、content-addressed derivation 与 recursive-nix。约 900 次实验得到链长均值 6.18、中位数 4、最长 46,与几何分布吻合。文章指出当前 --dry-run 等工具无法内省动态图,并讨论 Mario 模拟、状态空间搜索和爬虫等超出 lang2nix 的用法,同时留下图深度与规模边界未知的问题。
推荐收录:文章不是泛泛介绍 Nix 新特性,而是用类型系统和调度层差异解释动态 derivations 的根本变化,并给出可运行示例、实验数据和可迁移的搜索/爬虫等场景。适合构建系统、开发者工具和编程语言实现方向的读者,能帮助理解增量/动态依赖图的代价与当前工具链局限;主要风险是动态 derivations 仍属实验特性,文中 --dry-run 不可用等结论需结合版本验证。
工具笔记 Fzakaria Blog 2026/09/16
文章介绍作者用 Hilbert 曲线构建的 seenix.dev:一个完全在浏览器本地运行、无需服务端的单页应用,以“一字节一像素”的方式可视化 Nix closure。核心做法是把 closure 内各 store path 的 NAR 按名称排序拼接成一维字节流,再用 Hilbert 曲线折叠成正方形,从而保持字节局部性,使 store path、文件乃至 ELF section 都对应连续方形区域。布局只需 narinfo 中的 NarSize,因此整张图在下载任何 NAR 前即可毫秒级完成,缩放时再从 cache.nixos.org 按需取 NAR 并按字节类型上色(可打印 ASCII、控制字节、0x00 等)。作者据此验证某争议二进制实际不含 ffmpeg 与 ruby(41 个 path、234 MiB),并展示了 1,324 个 path、5.3 GiB 的 GNOME 桌面 closure,工具支持 nix path-info 导出与额外二进制缓存。其边界是主要用于探索与可视化,不改变 Nix 语义,且读者需具备基本 Nix 背景。
推荐收录:文章给出了明确且可复现的技术机制(Hilbert 曲线字节布局、仅凭 narinfo 提前绘图、缩放时按需拉取 NAR),并用真实 closure(含争议二进制与 GNOME 桌面)验证结论,而非停留在概念演示。适合使用 Nix/NixOS 的开发者、做二进制或依赖体积分析的工程师,以及关注可视化实现的人;其局部性布局与懒加载思路可迁移到其他大体积产物的可视化与审计场景。
技术文章 Fzakaria Blog 2026/09/12
文章指出成为 Nix 二进制缓存只需实现三个 GET 请求:nix-cache-info、对应 32 位哈希的 narinfo 元数据、以及 narinfo 中 URL 指向的压缩归档,客户端并不关心底层传输介质。作者据此把 nix copy --to file:// 产出的缓存目录发布到 GitHub Pages/Releases 与 npm 等静态文件服务,并用 npm 完整演示了打包、签名、发布,再从 unpkg 作为 substituter 拉取闭包并用 bwrap 运行的流程。文章还解释签名只覆盖 StorePath、NarHash、NarSize、References,不含 URL/FileHash,因此归档可托管于任意主机并仍通过校验。文末列举 gachix、DNS TXT、pastebin、OCI、npm 等替代实现,并指出 npm 不支持增量发布、每次版本重复上传整个闭包这一主要局限。
推荐收录:文章把 Nix 二进制缓存抽象为三个 GET 请求,并用 GitHub、npm、git 对象库等真实实现佐证,签名覆盖范围与 npm 无法增量发布等边界说明清晰。适合使用 Nix 的开发者及包管理、内容寻址存储方向读者,其最小接口与签名校验思路可迁移到自建缓存、制品分发等场景。
工具笔记 Fzakaria Blog 2026/09/09
文章介绍作者为 trynix 新增的 trynix-preview GitHub Action:它会在 Pull Request 下自动评论一条链接,评审者点击即可在浏览器标签页中启动 Linux 环境,并把该 PR 构建出的二进制加入 PATH,无需 clone、构建、服务器、SSH、Docker 或虚拟机。该 Action 不负责构建与缓存,只通过 nix eval 取出 store 路径,并把缓存地址与公钥交给浏览器,因此前提是目标路径已被构建并推入缓存(如 Cachix)。安全方面需在 fork PR 场景开启 allow-unsafe-pr-checkout,工作流运行于默认分支再检出 PR 代码以防 fork 篡改,并建议为 PR 构建使用隔离的私有缓存。作者也坦承大型二进制执行仍需 1-2 分钟,更适合中小型二进制的评审场景。
推荐收录。该文并非单纯工具发布,而是给出了可复制的工作流配置、缓存前置条件、fork PR 的安全权衡(默认分支运行、隔离私有缓存)以及大二进制启动耗时 1-2 分钟的明确边界。对设计 CI/CD 评审流程、探索浏览器内可执行环境或使用 Nix 的团队有直接可迁移价值。
工程实践 Fzakaria Blog 2026/09/05
文章介绍了一个名为 trynix 的浏览器内 Nix 包运行器,允许用户通过静态网页直接启动一个完整 Linux 虚拟机,并运行 nixpkgs 历史上任意版本的任意包。作者结合此前构建的 nixpkgs-multiverse、grail 和 omniflake 等工具,实现了“属性+版本号→store path”的映射;利用 cache.nixos.org 等公开缓存提供的 CORS 支持,使浏览器可以直接获取 NAR 包;再借助 QEMU 与 WebAssembly 在浏览器中启动真实的 x86_64 Linux 内核,并通过 9p 文件系统挂载内存中的 Nix store。文章还讨论了性能优化,如后台预取引擎和虚拟机快照恢复,使得首次启动约 4 秒、二次访问约 1.5 秒。作者分析了该方案的边界:二进制仍处于模拟执行、首次运行有翻译开销、闭包大小受制于标签页内存和 WebAssembly 的 32 位地址空间。最后作者展望了 PR 评测试用、Agent 产物共享、可复现 bug 报告、可运行文档和软件考古等应用场景。整体是一个完整的工程实践案例,展现了将多种既有技术组合成新系统的思路。
推荐收录。文章展现了真实工程系统的完整构建过程,从组件设计、缓存复用、性能优化到边界约束均有具体细节。对关注 Nix、WebAssembly、浏览器端执行或可复现构建的读者,文中的架构拆解和应用场景推演极具迁移价值,也有助于启发新的工具链设计。
技术文章 Fzakaria Blog 2026/09/02
这篇文章讨论在 Nix 生态中混用不同 nixpkgs revision 时产生的菱形依赖问题:同一进程可能经由不同依赖链载入同一库的两个版本,导致符号冲突或内存破坏,如 fluent-bit 自带的 zstd 与 libsystemd dlopen 的 zstd 互不兼容而破坏地址空间。作者在 grail 工具中新增 --one <attr> 约束,要求求解器为所选全部 revision 只保留指定库的单一版本,文中用 python3/postgresql 和 zstd/openssl 的示例展示约束如何让 python 回退到更早 revision,并在无解时精确报告会混合的版本。文章明确该保证仅到版本级 ABI 一致,不等于统一 commit 或 /nix/store 路径,若要严格同路径仍需强制单 revision;glibc 等具备向后兼容的库未来可以放宽。全篇以 SAT 求解器为底色,展示了把依赖一致性变成可求解约束的技术路线。
收录理由:文章不是空谈一致性,而是用真实崩溃案例和不含糊的求解输出展示了一种工程解法,并明确点出能得到与得不到的边界。适合 Nix/nixpkgs 维护者、依赖解析或包管理系统的设计者阅读;把多版本冲突转化为 SAT 约束并让求解器报告冲突的思路,也能迁移到其他语言生态。缺点是内容较垂直,要求读者具备 Nix revision 等前置知识。
工程实践 Fzakaria Blog 2026/09/01
文章围绕给 Nixpkgs 引入版本区间支持展开。作者利用 nixpkgs-multiverse 对 nixos-unstable 历史版本的索引,把传统包管理器中的依赖求解问题建模为 Answer Set Programming(ASP),并用 clingo 求解。工具 grail 提供类似 Spack 的查询语法,支持版本区间、共存组、日期范围等约束,能在数秒内找到满足多包版本条件的历史修订版本,并生成锁文件供 nixpkgs-multiverse 使用。文章还展示了如何在 derivation 中直接编写版本区间并在 build 时通过 import-from-derivation 完成解析。针对跨修订版本可能带来的 glibc 兼容问题,作者给出了基于 ELF 符号版本需求实现跨 era 混合的方案。目前该工具以命令行和 WebAssembly 演示形式提供,计划整合进 nixmultiverse.com。
推荐收录。文章不是抽象理念,而是用可运行的 grail 工具和一个实网索引给出了从版本区间语法、ASP 建模、求解策略到 glibc 兼容验证的完整方案,证据链清晰。适合对包管理器设计、依赖求解、SAT/ASP 应用或 Nix 生态深入探索的读者。文中的将版本历史当作可查询数据库的思路,以及用 ELF 元数据放宽兼容边界的做法,也具有跨生态的可迁移价值。
技术文章 Fzakaria Blog 2026/08/31
本文用 omniflake 索引的 11,936 个 Nix flake 数据,量化分析 `follows` 统一 nixpkgs 输入的安全性。作者统计各 flake 锁定 nixpkgs 的年龄、渠道来源和选择时的陈旧度,发现半数 flake 在选定时使用的 nixpkgs 不足 17 天,如今中位数已超过 506 天;约八成修订曾是 Hydra 构建的渠道发布,生态整体并非故意用旧版本,而是长期未更新。由此推断,`follows` 通常迫使 flake 用比原作者测试时新约一年半的 nixpkgs 构建,可能引入轻微破坏,尤其在 nix-darwin 场景。文章同时承认该研究只能从修订版本分布推断风险,不能直接测量构建失败率,结论属经验性参考。
本文是少见的以真实生态数据回答 `follows` 安全性的分析,提供了具体的年龄分布和渠道统计,可帮助 Nix 用户和库维护者理解风险并决定是否使用 `follows`。研究方法(利用索引和发布存档做交叉分析)也值得借鉴;但由于没有直接测量构建失败,结论应视为风险提示而非最终定论。
工程实践 Fzakaria Blog 2026/08/29
文章针对 Nix flakes 在管理输入时反复添加 follows、无法统一 nixpkgs 的痛点,提出了一个名为 omniflake 的单一 flake,将近一万两千个 flake 打包为一个输入。作者先解释了 flake.lock 的传递依赖和重复问题,说明 Nix 的惰性求值使大量输入在被访问前不会被拉取。随后描述了他为 Nix 上游修复的输入数量多时锁文件命名碰撞导致的二次复杂度问题,给出了优化前后性能对比。核心设计是 omniflake 只声明少量真实输入,通过内置 index.json 的 pin 信息和自定义加载器在请求时按需实例化各 flake,并支持 overrides 覆盖输入。文章还讨论了这个方案的边界,如部分 flake 缺少 flake.lock 时的变通,以及集中化与联邦化的权衡。
本文以真实的 Nix 生态痛点为出发点,不仅提出了 omniflake 这一新颖方案,还贡献了 Nix 上游性能修复,并附有清晰的机制解释和基准数据。适合 Nix 用户、包管理工具设计者和对惰性求值与依赖图感兴趣的系统工程师阅读。其中'用元数据代替真实输入、按需加载'的设计思路,以及性能问题的定位与优化方法,可以迁移到其他依赖管理或构建系统。
工程实践 Fzakaria Blog 2026/08/26
文章针对构建系统中用 llvm-objcopy 向 ELF 可执行文件附加 build info 时内存占用随文件大小线性增长的问题,提出了一种常量内存的 stamping 方案。作者通过测量确认 llvm-objcopy 的峰值 RSS 约为文件大小的两倍,并分析其根因:objcopy 需要将整个 ELF 读入内存以增加一个 section,并更新 section header table 和 .shstrtab。新方案让链接器在链接时预先发出一个仅含一字节的占位 section,使 section 的名字和 header 已经存在;之后的 stamping 步骤只需把 payload 追加到文件末尾,再原位修改该 header 的 sh_offset 和 sh_size 共 16 字节,完全不需要读取或重写文件其余部分。基准显示新方法内存占用恒定约 9.5 MiB,耗时与文件大小无关。文中给出了完整的 C 实现 elfstamp.c,并指出该技巧仅适用于非 SHF_ALLOC 的元数据 section,不影响内核加载。
推荐收录。文章用真实测量数据揭示了 llvm-objcopy 内存随文件大小线性增长的缺陷,并给出将内存占用降为常量的巧妙方案:利用链接器预留占位 section,stamping 时只追加数据和原位修改 16 字节 header。附带的 elfstamp.c 代码可直接迁移,适合构建系统、二进制后处理和大 ELF 注入元数据的工程师;其'专用小工具替代通用工具'的思路以及从现象到根因的分析方法也具有很强的可迁移性。需注意该方案仅适用于非 SHF_ALLOC 的 section,集成前需确认链接器与目标格式的兼容性。
技术文章 Fzakaria Blog 2026/08/25
本文介绍了一种名为 SELF 的可执行文件格式构想:将程序本身构建为一个 SQLite 数据库,利用 Linux 的 binfmt_misc 机制通过自定义解释器执行,使得可执行文件的内容、元数据乃至运行状态都可以用 SQL 查询和修改。作者给出了一个可运行的 proof-of-concept 服务器 self-httpd,该服务器的程序代码、网页内容、访问日志和业务数据全部存放在同一个 SQLite 文件中,运行时可对自身文件进行 ACID 事务写入,并支持在线更新页面、全文检索和跨版本迁移。文章对比了 redbean 的 ZIP 自解压方案,指出 SELF 借助 SQLite 将容器与查询能力合二为一。文中也说明了当前限制,例如 /proc/self/exe 不可用,以及原型仍较为粗糙。整体上展示了将可执行格式重新定义为数据库后,现有 SQL 工具链可以大幅简化二进制分发、部署和审计流程。
推荐收录。文章提出了一个真正可运行的原型,并用 self-httpd 演示了程序自身可查询、可事务更新、可全文检索等能力,不是空泛概念。它对研究可执行格式、系统软件架构和部署简化的读者有很强的启发价值,其将二进制内容映射为数据库行的方法可以直接迁移到其他工具链设计中。需要注意目前实现依赖 binfmt_misc 且尚不成熟,但作为长期参考和创意起点价值明显。
工程实践 Fzakaria Blog 2026/08/23
文章提出用 SQLite 数据库文件替代 ELF 作为 Linux 可执行格式,作者在 NixOS 上实现了名为 SELF 的原型。核心做法是把程序头、加载段、符号表等建模成 SQL 表,利用 SQLite 的 application_id 和 binfmt_misc 让数据库文件可直接执行,并编写 self-exec 解释器完成加载、重定位和跳转。文中还展示两种动态链接方案:通过 glibc rtld-audit 用 SQL 查询替换库查找,以及完全用 SQL 实现 dynamic linker;并把整个 userland 的 723 个可执行文件及其依赖打包进一个 611.9 MiB 的数据库。基准显示单文件体积约为 ELF 的两倍,启动有约 5ms 固定开销且缺页共享受限,但通过 closure 去重后整体体积反而略小于源 ELF。文章明确承认这是原型,兼容性和性能仍是适用边界。
推荐收录。文章不是概念空想,而是给出可运行的 SELF 原型、SQL schema、加载器和完整基准,并用一个 723 可执行文件的 userland 数据库验证了可扩展性。对操作系统、二进制格式、动态链接和数据库方向的工程师与研究者,它能启发将“格式”重新理解为可查询数据模型,且作者对体积、延迟和缺页共享的量化边界值得迁移。
技术文章 Fzakaria Blog 2026/08/20
文章以 nixpkgs-multiverse 的索引文件为背景,探讨如何在 Nix 求值过程中直接调用 SQLite 查询,避免大规模 JSON 整文件解析。作者依次介绍 builtins.exec、builtins.importNative、巨型 .nix 文件和 builtins.wasm 四种方案,并给出关键代码和基准。结果表明:fromJSON 与巨型 .nix 均为固定开销,exec 每条查询约 3.8ms,importNative 因句柄缓存几乎恒定,wasm 需约 2.5s 编译但查询仅 7ms/条。作者最终认为当前无一种适合正式发布,同时指出 wasm 的潜力。文章还覆盖 Nix 字符串无法表示二进制等边界问题。
推荐收录。文章以可复现代码和实测基准系统比较了四种在 Nix 中嵌入 SQLite 的方案,并坦诚列出各自的安全与性能缺陷。适合 Nix 扩展开发者和需要在构建/求值流程中内嵌查询能力的读者;其对比方法和性能分析可迁移到其他“运行时内嵌外部引擎”的场景。注意 builtins.wasm 仍属实验特性,相关 API 可能变化。
工程实践 Fzakaria Blog 2026/08/17
nixpkgs-multiverse 可从单个 flake 固定任意 Nix 包到历史任意版本。文章把版本固定建模为连续 revision 区间,目标是用最少 revision 点覆盖所有 pin,转化为贪心活动选择,O(n log n) 最优。若版本有空洞则 NP-完全,作者取最新连续段保持多项式可解。模拟显示 30 个近期版本 pin 只需约 10 个 revision;工具还提供最优性 plan、Nix API 与断言。需注意按 revision 分组可能拉回较早版本,且同版本字符串的闭包可能不同。
推荐收录。文章不是简单介绍工具功能,而是给出了清晰的算法建模、贪心最优性论证和 NP-完全边界,并用模拟数据验证收益。适合 Nix/Nixpkgs 用户、包管理工具开发者,以及对区间调度和工程权衡感兴趣的读者。可迁移价值在于把版本选择抽象成区间覆盖问题并利用贪心策略;主要风险是工具与 Nixpkgs 特定索引绑定,同类思路迁移到其他包管理器时需重新验证连续性假设。
工程实践 Fzakaria Blog 2026/08/14
文章介绍 nixpkgs-multiverse 项目的 fast mode,它让用户无需下载和求值完整 Nixpkgs 树即可直接获取任意历史版本的 store path。核心方法是利用 Nix 字符串的 context 机制,通过 builtins.appendContext 手动附加 path 上下文,并使用 mkFakeDerivation 技巧构造不依赖 --impure 的假派生,使 Nix CLI 仅从缓存便能实例化路径。作者解释了索引的构造方式:将 nixos-unstable 每期发布的 store-paths.xz 清单与 multiverse 的 (attribute, version) 索引 join 起来,得到每个版本的精确 store path。文章还讨论了边界,如 fake derivation 没有 drvPath 无法构建,需要 .out 后缀或通过 .eval 获取真实派生来支持 override 和 nix develop,且方案依赖 cache.nixos.org 长期保留所有历史路径(普查显示 271,187 个路径仍存活)。最后展示了配套的 mvs 命令行工具,可查询大小、反向依赖和识别 store path。
本文深入揭示了 Nix 求值与缓存的内部机制,提供了跳过求值直接引用 store path 的可行方案,并清楚说明了其局限。对于 Nix 重度用户和包管理工具开发者,文中的 context 操纵技巧与索引设计具有直接借鉴价值,适合作为 Nix 生态进阶参考收录。
技术文章 Fzakaria Blog 2026/08/11
文章介绍 nixpkgs-multiverse 项目,它通过一个 Nix flake 输入,提供 Nixpkgs 所有历史版本中每一版软件包的每一个独立版本。因 Nix 早于 FHS 的设计允许多版本共存,multiverse 收录了 304,484 个软件包版本对,涵盖 1,537 个 Nixpkgs 修订版,远超其他发行版;文中以 CPython 为例展示 246 个可并存的版本,并配有数据可视化对比。文章还说明 multiverse 帮助解决了 devenv 中依赖固定版本的长期问题,并介绍了 daysBehind 冷却窗口和 provenance 元数据特性。方案本质是 5 MB JSON 和 200 行 Nix 代码,并无复杂技术,但概念大胆,展现了 Nix 可复现构建与版本寻址的潜力。
本文展示了一个充分利用 Nix 可复现、多版本共存特性的创新案例,通过具体数据和真实工程问题解决(devenv 包固定)证明了其长期参考价值。适合对 Nix、开发环境可复现性及依赖管理感兴趣的开发者,文中的设计思路和方法可迁移到其他需要多版本支持或环境锁定的场景。
工程实践 Fzakaria Blog 2026/08/09
文章介绍 nixpkgs-multiverse 项目,通过一个 flake 输入提供 Nixpkgs 所有历史版本的惰性访问,解决多版本依赖时需固定多个 flake 输入的性能和易用性问题。核心方法是用 revisions.json 与 versions.json 索引包版本到修订的映射,并利用 builtins.fetchTree 按需获取;数据编码仅保留每个版本的最新出现修订,将索引大小控制在 5 MB 左右。性能实验表明,相比急切获取多个 flake 输入,该方案解析开销极低且遵循按修订计费原则。项目不构建或镜像任何内容,仅是对已有 Hydra 缓存的映射层,适合需要在 Nix 生态中灵活组合不同版本包的开发或构建环境。
推荐收录,因为它展示了一个真实的工程问题(Nix flake 多版本输入的性能与可用性冲突),并给出了完整的设计方案、数据优化与性能对比,具备可迁移的工程判断和工具设计思路。对使用 Nix、关注包管理与依赖分析的读者有直接参考价值,其惰性索引与按修订计费的设计也可启发其他需要高效版本查询的系统。
工程实践 Fzakaria Blog 2026/08/06
文章探索了利用Nix语言的惰性求值特性,将属性路径转化为Super Mario Bros. 3的按键输入序列。作者通过将每次按键操作定义为独立的派生(derivation),并使每个派生依赖前一帧的快照作为输入,从而实现了游戏状态的懒加载与增量构建。Nix store实际上充当了模拟器快照历史的持久层,分支或追加操作只需计算增量部分。文章还分析了递归深度限制(默认约2400次按键)、内核命令行参数长度限制(21,845次按键)以及构建时间线性增长等实际约束,并提出了通过文件输入绕过限制的方案。该工程案例展示了Nix派生机制在游戏状态机中的创意应用,但主要用于技术演示,性能开销较大。
推荐收录,因为这不是简单的技术玩梗,而是深入展示了Nix惰性求值、派生依赖和内容寻址存储的底层机制。文章提供了细致的基准测试和限制分析,对理解Nix的运行模型和扩展能力很有启发。适合对Nix或函数式构建系统感兴趣的工程师,其将输入序列拆分为可复用的派生单元的思想可迁移到其他需要增量构建或状态机复现的场景。
工程实践 Fzakaria Blog 2026/08/01
文章介绍了一个在 Bazel 中从 357 字节的 hex0 种子自举构建的 C++ 工具链。作者受 stage0 和发行版自举过程启发,利用 LLM 协助完成了这一机械但步骤繁多的工程,最终工具链能够无补丁编译 Bazel Central Registry 中的 Abseil 和 GoogleTest,并通过 236 项测试。工具链包含审计报告,利用 Bazel aspect 验证构建图中每个动作仅执行工具链自产的程序,确保了极高的封闭性。当前方案仍需系统提供的 shell,但显著提升了 Bazel 构建的可重现性,适用于对构建可信性、可移植性有要求的 C/C++ 项目。
推荐收录,因为它将一个很有挑战性的自举工具链工程在 Bazel 体系中完整实现,并用实际测试和审计报告证明了可行性。这对于关注构建可重现性、供应链安全以及工具链定制的工程师具有直接的参考价值,文中的自举流程和封闭性验证方法可直接迁移至类似基础设施建设项目。
技术文章 Fzakaria Blog 2026/07/31
文章深入分析了Nix沙盒配置(sandbox-paths)如何成为推导的隐式输入,破坏了推导作为完整构建配方的理想。作者通过一个极简示例演示:当沙盒中不挂载/truth时,推导输出“2+2=4”;挂载包含不实内容的/truth后,输出变为“2+2=5”,但输出哈希不变,说明相同的.drv可以产生不同内容。文章进一步讨论此问题的严重性:默认sandbox-paths取决于Nix二进制的编译选项(如是否带busybox),不同机器上的“相同”Nix版本可能因隐式输入差异而产生不可重复的构建。作者还结合自己构建OpenJDK的实例,说明Guix软件包假设不存在/bin/sh而Nix默认提供,导致构建过程静默走上不同分支并生成损坏产物,该损坏产物还被无心上传至二进制缓存。文章揭示了Nix设计中的一个根本性权衡:将sandbox-paths纳入推导会破坏缓存共享,而排除则损害可重复性。其边界在于仅讨论intensional模型,content-addressed derivations或可缓解。
文章通过一个简洁可复现的例子,直观展示了Nix沙盒路径如何成为隐式输入,破坏推导的完整性和可重复性,并结合作者构建OpenJDK的真实踩坑经历,揭示了该问题在跨机器构建和二进制缓存投毒中的实际风险。适合所有关注构建可重复性和供应链安全的Nix用户、DevOps工程师阅读;其揭示的“隐式输入”原理可迁移至任何追求封闭构建的系统,提醒我们在依赖缓存时需重新审视信任假设。
工程实践 Fzakaria Blog 2026/07/30
文章记录了在Nix包管理器中实现从源代码自举构建OpenJDK的完整过程,通过移植Guix的bootstrap链(jikes、GNU Classpath、JamVM等),从零开始逐步构建出OpenJDK 7至25,脱离了对预编译二进制JDK的依赖。作者详细对比了Nixpkgs传统依赖二进制seed与GuixPkgs全源代码构建的闭包差异,量化了引导额外引入的876个推导项,并指出共享的C++工具链占据闭包主体。该工作展示了可复现构建在持久化软件供应链中的进展,同时也揭示了当前JDK自举对特定历史工具链的依赖和构建环境的复杂性。
推荐收录,因为本文不是简单的工具介绍,而是提供了真实的工程方案和可复现的构建链细节,包括从jikes到OpenJDK 25的19次完整构建过程及闭包分析。适合关注可复现构建、软件供应链安全或Nix/Guix生态的开发者,文中的自举策略和依赖分析手法可直接迁移到其他编译型语言的自举实践中。
工程实践 Fzakaria Blog 2026/07/30
文章展示了“Guix by Nix”项目,通过 guix-transfer 工具将 Guix 的软件包派生图翻译为 Nix 派生,并利用 Nix 守护进程构建了一个可启动的虚拟机镜像。该镜像以 Guix 的 Linux-libre 为内核,用户空间全部来自翻译后的 Guix 软件包,并以 GNU Shepherd 作为 init 系统,完全排除了 systemd 和 D-Bus。作者提供了自动化审计机制,验证所有可执行文件和脚本解释器均源自 Guix 输出,确保无 Nixpkgs 组件混入。文章还讨论了与 Nixpkgs 混合、构建非 systemd 系统等潜在拓展,但明确当前仅为最小演示,不适合生产环境。该案例对理解构建系统互操作、可重现系统构建和 init 系统替换具有参考价值。
推荐收录,因为它不是简单的工具使用,而是展示了将 Guix 生态翻译到 Nix 构建系统的完整工程方案,并附带了可验证的审计链。这对研究构建系统、操作系统定制或探索 Nix 作为通用构建语言的读者有直接启发,文中跨生态翻译、派生图转换和自证明验证方法均可迁移到类似项目。
技术文章 Fzakaria Blog 2026/07/27
文章以一次误导性的平均延迟指标为切入点,系统介绍了如何通过多种可视化手段正确理解性能分布数据。作者使用一个合成数据集模拟 Web 服务缓存上线场景,展示平均值、中位数、百分位数给出矛盾结论的原因,并依次通过密度图、累计分布函数(CDF)、位移函数、山脊图、热力图和联合图揭示数据呈双峰分布的实质:缓存命中导致低延迟,缓存未命中的大请求造成长尾。文章重点强调 CDF 能同时展示所有分位数的变化,尤其当两条 CDF 曲线交叉时,单一统计量无法概括整体效果。文中所有图表附有可复现的 Nix 脚本,便于读者在自己的数据上实践。该文既是一堂生动的可视化教学,也是工程师避免数据误读的实用指南。
这篇博文通过清晰的可视化对比,有力地揭示了仅依赖平均值或单一百分位数做技术决策的陷阱,并提供了可直接复现的分析方法。其核心方法(尤其是 CDF 对比和位移函数)可迁移到任何涉及分布变化分析的场景,如性能优化、A/B 测试或系统监控。适合所有需要从数据中提取可靠结论的后端工程师、SRE 和数据分析师,是一份长期值得参考的实践指南。
技术文章 Fzakaria Blog 2026/07/27
文章深入分析 x86-64 大代码模型(-mcmodel=large)在处理线程局部存储(TLS)时的根本性缺陷。作者通过构造超过 2 GiB 的 .bss 和 .text 示例,对比普通数据访问与 TLS 访问的编译器重定位类型,指出尽管大代码模型为普通数据生成了 64 位重定位,但 TLS 访问序列仍使用 32 位立即数(如 R_X86_64_TPOFF32),导致二进制文件超出 2 GiB 时链接失败。进一步剖析 GCC 与 LLVM 生成的指令序列,揭示问题并非编译器实现缺陷,而是 x86-64 psABI 从未定义大代码模型下的 TLS 访问模式,使得 64 位 TLS 偏移无法编码到指令中。文章提供了可复用的 Python 脚本用于生成巨型目标文件,验证了现象的通用性,并指出该限制对有大量线程局部变量的静态链接可执行文件尤为严重。
本文并非泛泛而谈,而是通过可复现的构造实验和汇编级分析,定位到 x86-64 ABI 规范的一项具体缺失,揭示了大型二进制工程中的一个隐蔽陷阱。其直接证据清晰、方法可迁移,适合从事工具链、系统软件或性能敏感大型应用开发的读者参考。文章还提供了生成测试用例的脚本,有助于读者在自己的环境中验证和延伸研究,具备长期的参考价值。
技术文章 Fzakaria Blog 2026/07/21
本文介绍了作者通过向 Linux 内核提交补丁,使内核支持在 PT_INTERP 和 shebang 中使用 $ORIGIN 的过程。最初提议在 VFS 层直接添加支持,经 VFS 维护者 Christian Brauner 建议,最终采用 eBPF 和 binfmt_misc 实现可编程解释器选择。文章展示了具体的 eBPF 程序示例,并讨论了新的 loader substitution 模式(L 标志),该模式允许原生执行二进制文件并透明替换解释器,解决了传统 binfmt_misc 中进程标识和 /proc/self/exe 指向解释器的问题。作者计划在相关补丁进入内核主线后,为 NixOS 开发一个可选模块,通过引入新的程序段(如 PT_INTERP_NIX)来保持向后兼容性。该方法不仅支持 $ORIGIN,还可用于动态选择 QEMU 等解释器,边界在于需要内核版本支持且依赖 binfmt_misc 和 eBPF 基础设施。
本文记录了真实的内核开发协作过程,从动机、技术方案迭代到最终实现,展示了如何利用 eBPF 和 binfmt_misc 解决可重定位二进制文件的痛点。对 Linux 内核开发、Nix/Bazel 等构建系统使用者以及关注动态链接器机制的技术人员有直接参考价值,其可编程解释器选择的思路可迁移至其他需要动态加载或仿真环境的场景。
工程实践 Fzakaria Blog 2026/07/21
文章记录了作者为支持 Nix 的 relocatable binaries 而向 Linux 内核提交补丁的完整过程。最初尝试在 VFS 层直接支持 $ORIGIN 失败后,在 VFS 维护者 Christian Brauner 的建议下,转而利用 eBPF 和 binfmt_misc 实现可编程解释器选择。最终方案通过 eBPF 程序在运行时根据 ELF 文件路径动态确定解释器,无需修改内核主体,并衍生出新的分发模式(如 loader substitution 'L')以解决传统 binfmt_misc 导致的进程身份透明性问题。文章还讨论了该机制在 QEMU、shebang 等场景的扩展潜力,并保留了向后兼容性设计——通过新增 PT_INTERP_NIX 段来控制触发。作者展望了在 NixOS 中的集成计划,同时坦诚说明了内核参与门槛、eBPF 所需的配置依赖等边界。
该文以一线开发者的视角完整呈现了一项内核特性的工程实现路径,从问题定义、社区协作、技术方案演化到最终合入主线的全过程,具有很高的可迁移价值。对从事包管理、容器化或需要定制可执行文件加载流程的工程师而言,它不仅展示了 eBPF 在系统软件中的创新用法,还深入分析了 binfmt_misc 的传统缺陷与改进思路,是理解现代 Linux 可执行文件加载机制和内核贡献方法论的良好参考。
技术文章 Fzakaria Blog 2026/07/09
文章介绍了一款名为 anubis-fetch 的工具,用于绕过 Anubis 防火墙的工作量证明(PoW)挑战。作者首先描述了为 Linux 内核 BPF binfmt_misc 开发补丁时,遇到 AI 工具无法直接抓取 lore.kernel.org 的问题,继而开发了该工具。工具通过原生实现 PoW 求解、可选的 Chromium 回退,以及对 Chrome TLS/JA3 指纹的模拟,成功绕过了 Anubis 及 Cloudflare 的被动封锁。文章进而批判了 Anubis 的无效性:攻击者可以轻易摊销一次性成本,而人类用户每次访问都要付出等待时间和设备能耗,尤其对移动端、屏幕阅读器等用户形成排斥。作者通过粗略计算,估算了全球范围因 Anubis 挑战消耗的人数和能源,指出这种措施更像是一种累退税,未能阻止真正的 AI 爬虫,反而损害了开放 Web。全文兼具工具实现细节与社会影响分析,边界清晰,不涉及复杂系统设计,但提供了可复现的方法和对反爬技术局限的反思。
推荐收录,因为它不仅是一个工具介绍,更包含了对反爬技术的深度批判和实证分析。文中直接展示了绕过 Anubis 的具体代码思路与效果,并通过估算了这种防御措施对人类用户造成的隐性代价,证据充分。这篇文章适合安全工程师、Web 开发者以及关注互联网开放性的读者,其可迁移价值在于提醒设计反爬系统时需权衡防御真实威胁与用户体验的平衡,避免累退性设计。
个人心得 Fzakaria Blog 2026/06/29
文章回顾了作者在墨西哥 La Saladita 组织的 TacoSprint 2026,这是一场面向 Nix 社区的首次北美 sprint。作者从选址、搭网站、拉赞助到招募参与者,详细记录了新活动在报名不足、旅行安全顾虑和航班紧张上的现实阻力。活动期间,冲浪与编码交替的日程让团队保持了稳定节奏,并在一周内推进了动态链接、可重定位二进制、远程构建、模块系统、OCaml 运行时裁剪和跨发行版打包等工作。文中还提到 LLM agents 的交流,以及一篇仿学术风格的 trip report,整体更偏社区组织与生产力经验,而非单点技术教程。
可收录,因为它直接呈现了首个北美 Nix sprint 的组织过程、现实阻力和可持续协作节奏,适合开源社区组织者、Nix 贡献者和想提升团队产出的读者。需要注意的是,文章主要是 retrospective,技术细节分散,不适合作为某一技术方案的深入参考。
技术文章 Fzakaria Blog 2026/06/23
这篇文章深入讲解了 wrap-buddy 如何通过篡改 ELF 入口点、动态段和辅助向量,绕过 NixOS 上预编译二进制因动态链接器路径不兼容而无法运行的问题。作者先用一个最小 C 程序演示 patchelf/autoPatchelf 在特殊 ELF 布局下的失败场景,再逐步拆解 wrap-buddy 的做法:保存原始入口指令、清空 PT_INTERP、注入自定义 RUNPATH,并在内存中恢复原样后把控制权交给 NixOS 的动态加载器。文章的核心结论是:这种方案并不是通用替代品,而是面向“常规修补失效”的病理场景,为旧二进制兼容性提供了一条极低层但有效的路径。
推荐收录,因为它不是简单介绍 Nix 工具链,而是把 ELF 启动、动态链接与启动劫持的机制讲得非常透彻,适合长期作为系统底层兼容性问题的参考。读者可以迁移的不只是某个工具的用法,更是“当静态修补失败时,如何从进程启动链路下手”的分析方法。