使用 cargo-bisect-rustc 二分查找 Rust 编译器回归

2019 年 12 月 18 日 · Santiago Pastorino 代表 编译器团队

假设您刚刚更新了 Rust 编译器版本,并尝试编译您的应用程序,结果发现出现了以前不存在的错误。这很可能是由于编译器中的回归引起的。我们刚刚发布了 cargo-bisect-rustc,这是一个可以非常轻松地找到回归发生的确切时间的工具。

cargo-bisect-rustc 会自动下载 rustc 构建产物,并针对您提供的项目进行测试,直到找到回归为止。它至少会识别出触发回归的 nightly 版本;如果回归发生在最近的 168 天内,它甚至会找出确切的 PR,这通常对帮助我们解决问题非常有用。

cargo-bisect-rustc 最初由 Mark Rousskov 创建。我最近对其进行了扩展,使其更易于使用。

要安装该工具,请运行

cargo install cargo-bisect-rustc

查找回归

我们将使用 这个“旧的”已报告的 rustc 回归 作为示例

我们的应用程序仅包含以下文件

pub struct Slice<'a, T>(&'a [T]);

impl<'a, T: 'a> Slice<'a, T> {
    pub const EMPTY: Self = Slice ({
        let v: &[T] = &[];
        v
    });
}

fn main() {
    let s = Slice(&[1, 2]);
    assert!(s.0 != Slice::EMPTY.0);
}

然后我们运行 cargo bisect-rustc --end=2019-10-02

由于这个错误在 2019-10-03 被修复,我们使用 2019-10-02 作为结束时间。我们需要为这个特定的示例提供结束时间,因为这个错误在 2019-10-03 被修复,所以我们使用 2019-10-02 作为结束时间。如果您不提供结束时间,它会假设结束时间是今天的 nightly 版本或您当前安装的 nightly 版本。如果您不提供开始时间,就像我们现在这样,它会尝试通过回溯时间来找到一个。如果您知道失败的起始时间,只需提供该时间会更快。

默认情况下,它将在项目中运行 cargo build 并检查是否失败。在找到回归的 nightly 版本后,它会自动搜索引入回归的 commit。

让我们看看这个工具的实际操作

该工具首先下载各种 nightly 编译器,尝试找到程序可以正常工作的日期 ...

checking nightly-2019-10-02
std for x86_64-unknown-linux-gnu: 172.87 MB / 172.87 MB [===============================================================================================================================================================] 100.00 % 10.67 MB/s uninstalling nightly-2019-10-02
checking nightly-2019-09-30
...

一旦找到一个失败和一个正常工作的点,它就开始进行二分查找 ...

std for x86_64-unknown-linux-gnu: 173.43 MB / 173.43 MB [===============================================================================================================================================================] 100.00 % 12.82 MB/s uninstalling nightly-2019-09-29
tested nightly-2019-09-29, got No
searched toolchains nightly-2019-09-28 through nightly-2019-09-30
regression in nightly-2019-09-30

一旦找到 nightly 版本,它就开始搜索该 nightly 构建中包含的 PR ...

looking for regression commit between 2019-09-30 and 2019-09-29
fetching commits from 488381ce9ef0ceabe83b73127c659e5d38137df0 to 8431f261dd160021b6af85916f161a13dd101ca0
...
searched toolchains 488381ce9ef0ceabe83b73127c659e5d38137df0 through 8431f261dd160021b6af85916f161a13dd101ca0
regression in 0bbab7d99dde8620604fb265706dc8bff20345a7

最后,当它找到导致编译器崩溃的 PR 时,它会生成一个你可以复制和粘贴的错误报告!

==================================================================================
= Please open an issue on Rust's github repository                               =
= https://github.com/rust-lang/rust/issues/new                                   =
= Below you will find a text that would serve as a starting point of your report =
==================================================================================

# Regression found in the compiler

searched nightlies: from nightly-2019-09-28 to nightly-2019-09-30
regressed nightly: nightly-2019-09-30
searched commits: from https://github.com/rust-lang/rust/commit/488381ce9ef0ceabe83b73127c659e5d38137df0 to https://github.com/rust-lang/rust/commit/8431f261dd160021b6af85916f161a13dd101ca0
regressed commit: https://github.com/rust-lang/rust/commit/0bbab7d99dde8620604fb265706dc8bff20345a7
source code: URL OF A REPOSITORY THAT REPRODUCES THE ERROR

## Instructions

Please give the steps for how to build your repository (platform, system dependencies, etc.)
## Error

<details><summary>COLLAPSIBLE ERROR STACKTRACE</summary>
<p>

```bash
$ Paste the error the compiler is giving
```

</p></details>

这告诉我们回归是从 0bbab7d99dde8620604fb265706dc8bff20345a7 开始的,你可以查看 git 日志来找到 PR。 在这种情况下是 #64470

行动号召:尝试使用该工具

请尝试一下这个工具,如果您发现更新应用程序后它停止构建,则很可能是遇到了回归。正如您在工具执行结束时看到的那样,如果找到回归,该工具会为您提供一个报告,您可以将其粘贴到 Rust 仓库 中的 github issue 上。

行动号召:参与 cargo-bisect-rustc 的开发

该工具还有很多需要改进的地方,也有很多错误需要修复。有很多已报告的 issue 很容易修复,查看一下。您也可以联系我们。您可以在 Zulip 的 #t-compiler/cargo-bisect-rustc 流 中找到我和其他编译器贡献者和成员。如果您还没有注册,请在那里注册,不要犹豫提出问题,甚至如果您不知道从哪里开始,也可以给我发送直接消息。