Hacker News 中文摘要

RSS订阅

我讨厌编译器 -- I hate compilers

文章摘要

作者原以为相同输入会得到相同输出,但实际并非如此。文章讨论了Anubis项目引入基于WebAssembly的工作量证明检查,旨在统一客户端和服务器的检查逻辑,并解决客户端禁用WebAssembly时的兼容性问题。

文章总结

好的,这是根据您的要求,对原文主要内容进行的中文重述,保留了关键细节,并删减了与主题无关的内容(如网站页脚、标签、版权声明等)。


标题:我讨厌编译器

核心问题: 你可能会认为,给定相同的输入字节,编译器会输出相同的字节。但现实并非如此,情况很复杂。

项目背景: Anubis 项目即将引入基于 WebAssembly 的工作量证明检查机制,让网站管理员可以使用非 SHA256 的验证方式来保护网站。其核心目标之一是,客户端和服务器的验证逻辑在“同一个地方”定义,以确保两者同步运行。

遇到的挑战: 一个棘手的问题是,如果用户禁用了 WebAssembly 怎么办?为了不将这部分用户拒之门外,作者从“JavaScript 的诞生与死亡”演讲中获得灵感,决定将 WebAssembly 重新编译回 JavaScript。虽然这样生成的 JavaScript 会比原生 WebAssembly 慢,但至少能“最终”完成验证。

工具与困境: 作者需要的工具是 wasm2js(来自 binaryen 项目)。虽然 Linux 发行版有打包,但版本过旧,输出结果与开发机上的版本不一致。为了确保构建的可复现性,作者决定将特定版本的 wasm2js 捆绑到项目中。他通过 wasi-sdk 将 wasm2js 本身编译成了 WebAssembly。

可复现构建的难点:

  1. 非确定性输出: 编译器并非总是确定性的。一个简单的例子是,C/C++ 代码中使用 __DATE____TIME__ 宏,会导致每次编译的输出都不同,因为编译时间被写入了二进制文件。

  2. Clang 的“小动作”: Clang 在链接时会静默调用 $PATH 中的 wasm-opt 工具来优化输出。如果系统自带的 wasm-opt 版本过旧(例如在作者的 ARM 机器上),它无法处理新的 WebAssembly 异常处理指令,导致构建失败。解决方案是在链接时传递 --no-wasm-opt 参数来禁用此行为。

  3. 地址布局影响排序: 作者使用的 Clang 版本在异常处理代码生成中,依赖于地址的敏感信息。原始指针值会泄露到 try_table 块的输出顺序中,导致每次构建的结果有约 29 字节的差异。这在 x86_64 和 ARM64 架构上表现也不同。

解决方案:

  • 使用 setarch --addr-no-randomize 禁用地址空间随机化。
  • 为 x86_64 和 ARM64 两种架构分别创建已知正确的 SHA256 校验和。
  • 设置 CI 任务,在两种架构上分别运行构建,并校验输出是否与记录的校验和匹配,以确保构建在同一架构内是确定性的。

结论: 作者承认,跨架构的完全可复现构建是一个上游 LLVM 的 bug,他目前无力解决。目前,确保构建在单一架构内是确定性的,可能已经足够好了。

评论总结

根据评论内容,总结主要观点如下:

1. 关于确定性构建的争议 - 支持方认为输出等价即可,无需强制一致(charcircuit: "As long as the program is equivalent there isn't an actual problem here") - 反对方指出非确定性输出是编译器bug(pertymcpert: "If Clang generated non-deterministic output due to pointer addresses then that's a bug")

2. 底层工程与LLM的局限性 - 底层开发依赖特定环境,LLM难以处理隐含假设(jdw64: "low level thinking tends to be tied to specific environments... LLMs do not seem to be very good at knowing these things") - 硬件差异和协议差异使技术生命周期缩短(jdw64: "protocol differences between vendors are far too severe")

3. 对Anubis方案(PoW+Wasm)的批评 - 能源消耗与可访问性问题(antirez: "force each browser to compute a lot of hashes... creating accessibility problems") - PoW应产生有用输出(KolmogorovComp: "surprised by Anubis' decision not to make the PoW have a useful output") - 用户禁用Wasm时的兼容性困境(znpy: "what do you do when the client has Javascript disabled?")

4. 替代方案建议 - Nix构建系统可解决确定性构建问题(edude03: "what all the problems they're describing literally is solved by nix") - 使用polywasm直接运行原始Wasm(evmar: "use polywasm to run the original wasm in place")

5. 对文章标题的质疑 - 标题与内容不符(ComputerGuru: "the article is not at all congruous with the conclusion in the clickbait title") - 更准确标题应为"可重现构建很难"(inigyou: "Better title: Reproducible builds are hard")