.

谷歌宣布支持在Chromium项目中使用

白癜风终于治好了 http://www.kstejiao.com/m/

我们很高兴地宣布,Chromium项目将在未来支持在Chromium中使用来自C++的第三方Rust库。为此,我们现在正积极寻求将生产Rust工具链添加到我们的构建系统中。这将使我们能够在明年内将Rust代码包含在Chrome二进制文件中。我们起步缓慢,并且对一旦准备就绪我们将考虑哪些库设定了明确的期望。

在这篇博文中,我们将讨论我们是如何做出此时支持第三方Rust库的决定的,而不是在Chromium中更广泛地使用Rust。

为什么我们选择将Rust引入Chromium

我们将Rust引入Chromium的目标是提供一种更简单(无IPC)和更安全(整体C++复杂性较低,沙箱中也没有内存安全错误)的方式来满足两个规则,以加快开发速度(更少的代码编写,更少的设计文档,更少的安全审查)并提高Chrome的安全性(增加没有内存安全错误的代码行数,降低代码的错误密度)。我们相信我们可以使用第三方Rust库来实现这一目标。

Rust是由Mozilla开发的,专门用于编写浏览器,因此Chromium最终也开始依赖这项技术是非常合适的。感谢Mozilla为系统软件行业做出的巨大贡献。Rust是一个令人难以置信的证据,证明我们应该能够期望一种语言在提供安全性的同时还具有高性能。

我们知道C++和Rust可以通过cxx、autocxxbindgen、cbindgen、diplomat和(实验性的)crubit等工具很好地协同工作。但是也有局限性。我们可以预期这些限制的形式会通过新的或改进的工具及时改变,但这里的决定和描述是基于当前的技术状态。

Chromium将如何支持Rust的使用

Chrome安全团队一直在投入时间研究我们应该如何将Rust与我们的C++代码一起使用。了解逐步转向编写Rust而不是C++的含义,即使在我们的软件堆栈中间。安全、简单和可靠的互操作的限制可能是什么。

根据我们的研究,我们为Chromium取得了两个成果。

目前,我们将仅在一个方向上支持互操作,从C++到Rust。Chromium是用C++编写的,大部分堆栈帧都是C++代码,从main()到exit(),这就是我们选择这个方向的原因。通过将互操作限制在一个方向上,我们可以控制依赖树的形状。Rust不能依赖于C++,因此它无法了解C++类型和函数,除非通过依赖注入。这样,Rust就不能登陆任意的C++代码,只能登陆从C++通过API传递的函数。我们暂时只支持第三方库。第三方库是作为独立组件编写的,它们不包含有关Chromium实现的隐含知识。这意味着他们拥有更简单且专注于他们的单一任务的API。或者,换句话说,它们通常具有狭窄的界面,没有复杂的指针图和共享所有权。我们将审查为C++使用而引入的库,以确保它们符合这一期望。

Chromium中Rust和C++之间的互操作

我们观察到,迄今为止,大多数成功的C/C++和Rust互操作故事都是通过狭窄的API(例如QUIC或蓝牙库、Linux驱动程序)或通过明确隔离的组件(例如IDL、IPC)围绕互操作构建的。Chrome建立在基础但非常广泛的C++API之上,例如//content/public层。我们研究了针对这些类型的API构建Rust组件对我们意味着什么。在较高的层次上,我们发现由于C++和Rust遵循不同的规则,事情很容易偏离正轨。

例如,Rust通过依赖于两个输入的静态分析来保证时间内存安全:生命周期(推断或显式写入)和独占可变性。后者与Chromium的大部分C++的编写方式不兼容。我们在整个系统中持有冗余的可变指针,以及提供多条路径以到达可变指针的指针。我们有周期性可变数据结构。在我们的浏览器进程中尤其如此,它包含一个巨大的互连(可变)指针系统。如果这些C++指针也以复杂或长期存在的方式用作Rust引用,则需要我们的C++作者了解Rust的别名规则并防止违反它们的可能性,例如:

从一个函数中返回同一个可变指针两次,其中第一个可能仍然保留。将一个可变的重叠指针传递给Rust,以一种它们可以同时作为引用保存的方式。通过共享或可变引用对Rust可见的变异状态。

如果没有通过编译器和类型系统提供支持的互操作工具,开发人员将需要了解Rust编译器所做的所有假设,以免违反C++中的这些假设。在这个框架中,C++很像不安全的Rust。虽然不安全的Rust对项目来说成本很高,但它的成本是通过保持封装和尽可能低的方式来管理的。同样,C++的全部复杂性需要从安全的Rust中封装出来。为互操作而设计的窄API可以提供类似的封装,我们希望互操作工具可以以其他方式提供封装,从而允许语言之间使用更广泛的API。

高级摘要是没有额外的互操作工具支持:

跨语言传递指针/引用是有风险的。语言之间的窄接口对于使正确编写代码成为可能至关重要。

任意代码之间的任何跨语言互操作都会带来困难,因为一种语言的概念在另一种语言中找不到。对于调用C++的Rust,绑定生成器很难支持对模板或继承等语言特性的支持。对于C++调用Rust,proc宏和特征是提供类似挑战的例子。有时,阻抗不匹配代表为任何一种语言做出的有意设计选择,但它们也意味着对语言之间的FFI(互操作)的限制。我们依靠互操作工具以一种对另一种语言有意义或不允许的方式对每种语言的思想进行建模。

从Chromium访问Rust生态系统

这些挑战提供了一个机会,既可以使互操作更容易、更无缝,也可以从任何一种语言访问更广泛的库。谷歌正在投资Crubit,这是一项关于如何提高C++和Rust之间互操作保真度以及如何表达或封装每种语言对另一种语言的要求的实验。

Rust生态系统非常重要,尤其是对于像Chromium这样以安全为中心的开源项目。这个生态系统是巨大的(crates.io上有96k+个板条箱)并且在不断增长,包括来自包括谷歌在内的整个系统开发行业的投资。Chrome严重依赖第三方代码,我们需要跟上第三方投资的进展情况。至关重要的是,我们要为将Rust纳入Chromium项目而提供支持。

我们将遵循这一策略来建立规范,并通过第三方流程保持一定程度的API审查,同时我们展望互操作性支持的未来,推动Rust和C++之间可行和合理的界限。

其他一些相关内容

内存不安全是一个全行业的问题,使用Rust是推动该领域发展的战略之一。最近,如果您有兴趣了解更多信息,Android和Apple都发布了一篇关于该主题的精彩博文。借助Chrome的数百万行C++,我们仍在努力通过MiraclePtr等项目来提高C++的安全性。




转载请注明:http://blog.hzbdfjk.com/sstx/8532.html