☰
如何编译出可调试的 rustc:rust.debug 配置、panic 时获取 backtrace 与 -Z 标志
2026/10/21 4:43:08 网站建设 项目流程

如何编译出可调试的 rustc:rust.debug 配置、panic 时获取 backtrace 与 -Z 标志

【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust

当你需要修改 rustc 编译器本身,或者在本地复现一次 Internal Compiler Error(ICE,编译器内部错误)时,默认构建的 rustc 几乎没有调试信息:backtrace 里没有行号,用 GDB 单步调试也没有符号。这篇文章给出 rust 仓库文档中记录的操作路径:在bootstrap.toml中配置rust.debug,重新编译出一个带调试信息的 rustc,并在 panic 时通过RUST_BACKTRACE=1获取带行号的栈回溯,以及使用-Z不稳定标志辅助诊断。

适用前提:你要构建的是 rust 仓库自身的编译器(通过 bootstrap 构建系统),而不是普通的 Rust 程序。构建入口是仓库根目录下的./x脚本,运行它需要本机已安装 Python。

准备:clone 仓库并创建 bootstrap.toml

按 构建指南 的步骤获取源码并初始化配置:

git clone https://github.com/rust-lang/rust.git cd rust ./x setup

./x setup会创建一份带合理默认值的bootstrap.toml。所有可调项的完整清单和说明在 bootstrap.example.toml 中,rust.debug相关选项的默认值以该文件中的注释为准。

磁盘空间要求(均来自构建指南与调试指南):

  • 构建 stage1 编译器大约需要 10~15GB 可用空间;
  • 若后面把rust.debuginfo-level设为 2,会用到"35GB 以上"磁盘,且编译时间明显变长(文档原文提示 "upwards of 35GB")。

配置 rust.debug:修改 bootstrap.toml

默认情况下 rustc 不带大部分调试信息(见 compiler-debugging.md)。在bootstrap.toml中加入:

rust.debug = true

根据 bootstrap.example.toml 的注释,rust.debug = true会同时影响若干未显式配置的选项,包括rust.debug-assertions(调试断言,代价是少量运行时变慢)、rust.debug-logging(保留debug!/trace!调用)、rust.overflow-checks,而rust.debuginfo-level的默认值会变为 1(rust.debug = true时)。也就是说rust.debug = true一次开启了debug-assertions、debug-logging等一组选项;如果你想单独微调,可以显式配置这些子项。

用 GDB 调试 rustc 时的额外配置

如果你要用 GDB 调试 rustc,需要完整符号信息,此时把 debuginfo 级别设为 2:

rust.debug = true rust.debuginfo-level = 2

文档对这两级有明确区分:

  • debuginfo-level = 1(debug = true时的默认值):可以跟踪执行路径,但丢失符号信息;
  • debuginfo-level = 2:符号信息完整,但会生成数 GB 的 debuginfo,显著拖慢链接过程,并占用 35GB 以上磁盘。

另外两个与调试相关的边界条件(来自 compiler-debugging.md):

  1. 默认配置会启用symbol-mangling-versionv0,这要求 GDB 至少是 v10.2。GDB 版本更低时,需要在bootstrap.toml中禁用新符号方案:

    rust.new-symbol-mangling = false
  2. 修改任何配置项之后必须重新构建编译器,配置才会生效:

./x build

验证构建出的 rustc

构建完成后,把 stage1 工具链链接到 rustup(quickstart 中的做法):

rustup toolchain link stage1 build/host/stage1 rustc +stage1 -vV

文档给出的rustc +stage1 -vV示例输出中,版本号以-dev结尾(如rustc 1.48.0-dev),说明工具链指向你本地构建的编译器。注意该自建工具链不包含cargo,rustup 会回退使用已安装的nightly/beta/stable工具链中的cargo。

panic(ICE)时获取 backtrace

rustc 发生 ICE 时,设置环境变量RUST_BACKTRACE=1即可获得panic!的栈回溯,和普通 Rust 程序一样:

RUST_BACKTRACE=1 rustc +stage1 error.rs

backtrace 的信息量取决于编译 rustc 时是否配置了debug = true:

  • 默认配置(未设rust.debug = true)下,backtrace 没有行号,只到函数级别。文档示例(节选):

    stack backtrace: 0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace ... 32: rustc_typeck::check_crate ... 37: rustc_driver::run_compiler
  • 设置debug = true后,每帧会附带文件:行号位置信息。文档示例(节选):

    stack backtrace: 7: rustc_typeck::check::cast::CastCheck::check at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:572 ... 34: rustc_driver::run_compiler at /home/user/rust/compiler/rustc_driver/src/lib.rs:253

    (以上两段均为文档示例,具体帧数、路径和行号会随你的代码版本变化。)

两个相关的环境变量与已知限制:

  • RUSTC_ICE=0可以禁止 rustc 在 ICE 时向当前工作目录写rustc-ice-<timestamp>-<pid>.txt文件;默认是会产生这个文件的。
  • 文档明确说明 backtrace 在 MinGW 上不可用("backtraces don't work on MinGW")。如果 backtrace 全是unknown,文档建议改用 Linux、macOS 或 Windows 上的 MSVC 工具链环境。
  • 想要更详细的回溯可用RUST_BACKTRACE=full(文档示例输出中的 note 提到该取值)。

用 -Z 标志辅助诊断

编译器自带一批-Z不稳定标志,它们只在 nightly 上生效,其中许多对调试很有用。查看完整列表:

rustc +stage1 -Z help

文档重点介绍了下面几个:

定位错误消息的产生点:-Z treat-err-as-bug

-Z treat-err-as-bug=n让编译器在第n个错误处直接 panic,从而拿到错误发生点的 backtrace;省略=n时默认按 1 处理,即遇到第一个错误就 panic。文档中的完整流程(示例):

fn main() { 1 + (); }

先正常编译,确认能复现错误:

rustc +stage1 error.rs

加上-Z treat-err-as-bug后,编译器在处理该错误时 panic,输出中会包含internal compiler error: unexpected panic以及指向编译器源码位置的栈回溯(文档示例中回溯指向rustc::traits::error_reporting::...::report_selection_error等帧)。

查看错误创建位置:-Z track-diagnostics

-Z track-diagnostics利用#[track_caller]在每条错误消息旁打印它的创建位置,文档示例输出:

error[E0277]: cannot add `()` to `{integer}` -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs:638:39

文档指出它与-Z treat-err-as-bug的差异:它会对所有错误打印位置、不需要带调试符号编译的编译器、也不必阅读长栈回溯。

其他有用标志

  • -Z verbose-internals:打印更多对调试有用的内部信息(文档原话是 "generally enables printing more info that could be useful for debugging");
  • -Z eagerly-emit-delayed-bugs:把 delayed bugs 变成正常错误直接暴露出来,可与-Z treat-err-as-bug组合使用,停在特定的 delayed bug 处并获取 backtrace。

限制与后续

  • 任何bootstrap.toml配置改动后都要重新./x build才生效;
  • rust.debug = true的编译器因调试断言等检查会"稍慢但仍可用"(bootstrap.example.toml 原文注释);
  • debuginfo-level = 2只建议在你确实用 GDB 等调试器单步调试时开启,平时用默认的 level 1 即可跟踪执行路径;
  • 需要更深入调试时,文档还分别提供了查询调试(incrcomp-debugging)、后端调试(backend/debugging)、借用检查器调试(borrow-check/debugging)以及 tracing 日志输出的专门章节,均可从 compiler-debugging.md 内链接进入。

【免费下载链接】rustEmpowering everyone to build reliable and efficient software.项目地址: https://gitcode.com/GitHub_Trending/ru/rust

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询