加载失败
Google 在多篇博文中披露了在 Android/Chromium 中推广 Rust 的实践与指标(例如大规模 Rust 代码中极低的内存安全缺陷密度与更低的回滚率),引发社区对数据可靠性、方法论和可复制性的热烈讨论。评论基于对内存安全(use‑after‑free、越界、双重释放等)、编译器(LLVM)、工具链(Cargo)与 Android 构建生态(NDK、Soong、Bazel/Blaze)的理解,分别从统计学、工程成本与语言设计角度展开辩论。核心争点包括:Google 的观测是否被旧 C/C++ 历史债务或样本选择所扭曲、Rust 把风险集中到 unsafe 的实际效果、以及在大型闭环平台中渐进替换高风险组件是否比全面重写更可行。理解这些讨论需要既懂内存安全问题的技术细节,也要了解大型代码库的测试、模糊测试(fuzz)、SAN/ASAN 措施与构建/发行的实际运维成本。
Google 内部报告与博文指出,在大约 5 百万行 Rust 代码中只发现 1 个潜在内存安全漏洞,按密度与 Android 既有 C/C++ 代码对比报告了约 1000× 的内存安全缺陷降低,并且新代码的回滚率也显著下降(文章提到约 4× 下降)。支持者强调 Rust 把风险集中到少量的 unsafe blocks(报告估计约 5% 的代码位于 unsafe 中),使得模糊测试、审计和形式化证明能更有针对性;同时 Rust 的类型系统(Option/Result、enums、trait)与借用检查器(borrow checker)被认为能本质上减少可利用的内存缺陷。评论还提到 Google 优先将与不受信数据交互的组件(如解析器、网络、Bluetooth 子系统)迁移为 Rust,并结合大规模自动化检测(fuzz、SAN/ASAN)来验证效果,许多人把这些工程与度量视为在大型闭环系统中可量化的安全与可维护性收益。
反对者指出用已存在多年、包含历史负债的 C/C++ 代码与刚写的新 Rust 代码直接比较会产生偏差:Rust 样本的内存安全缺陷数量极小(N=1),统计误差很大;而 Google 之前的分析显示五年历史代码的漏洞密度比新代码低约 7.4×,因此时间尺度与样本异质性会影响结论。批评者还强调重写通常选择易于测试或已知问题集中的模块(选择性迁移会放大效果),并提醒图表展示的绝对量/百分比差异及多语言混合可能误导读者。总体观点是这些观测性数据有价值,但不能直接证明因果关系,需控制混淆变量并做长期对照追踪才能更可靠地评估 Rust 的真实净效应。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6]
许多评论指出 Rust 的门槛与持续成本:借用/生命周期等概念需要较长学习曲线,编译成本高部分源于 rustc 向 LLVM 传输大量 IR 以及 monomorphization(为每种具体泛型实例生成代码),虽然用 cargo check 可部分缓解。Cargo 被一方面称为“一体化的优点”(依赖、构建、发布统一),另一方面也被批评为对发行与预编译二进制分发不友好、实现上不够透明,给包管理和发行版维护带来额外工作。Android 生态实践层面有人抱怨官方 NDK/Android Studio 对用户态 Rust 的一体化支持不足,许多绑定、混合调试与发布流程仍需社区补上,这些现实成本是评估迁移回报时必须考虑的折衷。
反对者强调内存安全只是缺陷类别之一,逻辑缺陷、设计错误、功能退化或实现错误仍会发生且可能因重写而增加;现实案例(如一些针对 Ubuntu 的 Rust 大规模改造问题)显示半成品或不当重写会破坏功能并引入新漏洞。评论中提议可通过 ASAN、现代 C++ 实践、静态分析器与严格测试来缓解内存问题,而无需全面、暴力式地重写整个代码库;此外重写的组织成本(培训、回滚、客户付费等)也常被低估。总体观点是将 Rust 视为工具而非银弹,决策应权衡内存安全收益与重写带来的系统性风险与运营成本。
讨论详细关注企业级逐步迁移的实际做法:Google 在 Android 与 Chromium 中选择性地用 Rust 替换高风险组件(例如 Bluetooth 子系统、PNG/JSON/字体解析器),并借助内部构建(Soong 在 Android 源码中调用 rustc;企业内部也使用 Blaze/Bazel)来集成 Rust。评论指出官方 NDK 尚未对 Rust 用户态提供同等一体化支持,导致 Android Studio、NDK API 的 Rust 绑定、混合语言调试和发行流程仍需社区工作;但在 Google 这样能控制部署和测试的闭环环境中,渐进替换高风险模块被认为最可行。跨公司案例(例如 Microsoft 改写 SymCrypt)也被引用,说明大型团队在性能与安全约束下更可能采取此类策略。
评论把 Rust 看作将若干已有编程语言理论与实践(函数式语言特性、type classes/traits、associated types、迭代器、所有权/生命周期)工程化并与现代编译链(LLVM)结合的产物,而非完全全新发明。具体讨论包括:早期语言(如 OCaml、Haskell)的理论对 Rust 的影响、某些类型系统特性(associated types/type families)在 1990 年代前后不可用导致当时难以实现同样的设计、以及泛型实现策略(monomorphization 导致编译与代码膨胀、polymorphization 为可能替代方案)。这些观点把 Rust 的成功归因于把成熟理论、现代编译器(LLVM)和工程化工具链整合到一起的时机与实现细节。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6]
unsafe blocks: Rust 中标记为 unsafe 的代码块,允许程序员绕过编译器的部分内存/借用检查以执行低级操作(例如 FFI、指针算术);进入 unsafe 后由人为负责保证内存安全,Google 报告中大约 5% 的代码位于 unsafe 中。
borrow checker: Rust 编译器用于在编译期基于所有权(ownership)与借用(borrowing)规则检查生命周期的机制,旨在防止 use‑after‑free、数据竞争与悬挂引用等内存错误。
Cargo: Rust 的官方包管理与构建工具(package manager / build tool),负责依赖解析、构建与发布;它简化了开发流程但也因二进制分发与包治理在发行版支持上被诟病。
NDK (Android Native Development Kit): Android 提供给开发者的本地层工具链和 API 集合,用于构建 C/C++ 本地库;评论指出 Android 官方对用户态 Rust 的一体化支持仍有限,许多集成工作需社区完成。
Soong: Android 开源项目使用的构建系统之一(Google/Android 的源码构建工具),在 Android 构建流水线中可以调用 rustc 以构建 Rust 代码。
LLVM: 一个广泛使用的编译器基础设施与优化后端,rustc 通常生成 LLVM IR 并交由 LLVM 优化与生成机器码;这一设计与 Rust 在编译时间和传输大量中间表示(IR)上的开销有关。
monomorphization / polymorphization: 泛型实现策略:monomorphization 为每个具体类型生成独立代码实例(提高性能但放大编译时间与二进制体积),polymorphization 或类型擦除则可减少实例化,但需要不同的运行或类型机制。
ASAN (AddressSanitizer): 一种运行时内存错误检测工具,用于在测试/CI 中捕获越界访问、未初始化内存等问题;评论认为 ASAN 是重要检测手段但不能完全替代语言级静态保证。
Wuffs: Wuffs(Google 开源的解析器/语言/库)旨在为文件解析提供编译时空间内存安全与高性能,但采用门槛与集成成本较高,因而在替换现有解析器时推广受限。