1 # Debugging the compiler
2 [debugging]: #debugging
6 This chapter contains a few tips to debug the compiler. These tips aim to be
7 useful no matter what you are working on. Some of the other chapters have
8 advice about specific parts of the compiler (e.g. the [Queries Debugging and
9 Testing chapter](./incrcomp-debugging.html) or the [LLVM Debugging
10 chapter](./backend/debugging.md)).
12 ## Configuring the compiler
14 By default, rustc is built without most debug information. To enable debug info,
15 set `debug = true` in your config.toml.
17 Setting `debug = true` turns on many different debug options (e.g., `debug-assertions`,
18 `debug-logging`, etc.) which can be individually tweaked if you want to, but many people
19 simply set `debug = true`.
21 If you want to use GDB to debug rustc, please set `config.toml` with options:
30 > This will use a lot of disk space
31 > (upwards of <!-- date-check Aug 2022 --> 35GB),
32 > and will take a lot more compile time.
33 > With `debuginfo-level = 1` (the default when `debug = true`),
34 > you will be able to track the execution path,
35 > but will lose the symbol information for debugging.
37 The default configuration will enable `symbol-mangling-version` v0.
38 This requires at least GDB v10.2,
39 otherwise you need to disable new symbol-mangling-version in `config.toml`.
43 new-symbol-mangling = false
46 > See the comments in `config.toml.example` for more info.
48 You will need to rebuild the compiler after changing any configuration option.
52 The compiler has a bunch of `-Z` flags. These are unstable flags that are only
53 enabled on nightly. Many of them are useful for debugging. To get a full listing
54 of `-Z` flags, use `-Z help`.
56 One useful flag is `-Z verbose`, which generally enables printing more info that
57 could be useful for debugging.
59 ## Getting a backtrace
60 [getting-a-backtrace]: #getting-a-backtrace
62 When you have an ICE (panic in the compiler), you can set
63 `RUST_BACKTRACE=1` to get the stack trace of the `panic!` like in
64 normal Rust programs. IIRC backtraces **don't work** on MinGW,
65 sorry. If you have trouble or the backtraces are full of `unknown`,
66 you might want to find some way to use Linux, Mac, or MSVC on Windows.
68 In the default configuration (without `debug` set to `true`), you don't have line numbers
69 enabled, so the backtrace looks like this:
73 0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
74 1: std::sys_common::backtrace::_print
75 2: std::panicking::default_hook::{{closure}}
76 3: std::panicking::default_hook
77 4: std::panicking::rust_panic_with_hook
78 5: std::panicking::begin_panic
79 (~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
80 32: rustc_typeck::check_crate
81 33: <std::thread::local::LocalKey<T>>::with
82 34: <std::thread::local::LocalKey<T>>::with
83 35: rustc::ty::context::TyCtxt::create_and_enter
84 36: rustc_driver::driver::compile_input
85 37: rustc_driver::run_compiler
88 If you set `debug = true`, you will get line numbers for the stack trace.
89 Then the backtrace will look like this:
93 (~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
94 at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:110
95 7: rustc_typeck::check::cast::CastCheck::check
96 at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:572
97 at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:460
98 at /home/user/rust/compiler/rustc_typeck/src/check/cast.rs:370
99 (~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
100 33: rustc_driver::driver::compile_input
101 at /home/user/rust/compiler/rustc_driver/src/driver.rs:1010
102 at /home/user/rust/compiler/rustc_driver/src/driver.rs:212
103 34: rustc_driver::run_compiler
104 at /home/user/rust/compiler/rustc_driver/src/lib.rs:253
107 ## Getting a backtrace for errors
108 [getting-a-backtrace-for-errors]: #getting-a-backtrace-for-errors
110 If you want to get a backtrace to the point where the compiler emits an
111 error message, you can pass the `-Z treat-err-as-bug=n`, which will make
112 the compiler panic on the `nth` error on `delay_span_bug`. If you leave
113 off `=n`, the compiler will assume `1` for `n` and thus panic on the
114 first error it encounters.
116 This can also help when debugging `delay_span_bug` calls - it will make
117 the first `delay_span_bug` call panic, which will give you a useful backtrace.
132 $ rustc +stage1 error.rs
133 error[E0277]: cannot add `()` to `{integer}`
137 | ^ no implementation for `{integer} + ()`
139 = help: the trait `Add<()>` is not implemented for `{integer}`
141 error: aborting due to previous error
144 Now, where does the error above come from?
147 $ RUST_BACKTRACE=1 rustc +stage1 error.rs -Z treat-err-as-bug
148 error[E0277]: the trait bound `{integer}: std::ops::Add<()>` is not satisfied
152 | ^ no implementation for `{integer} + ()`
154 = help: the trait `std::ops::Add<()>` is not implemented for `{integer}`
156 error: internal compiler error: unexpected panic
158 note: the compiler unexpectedly panicked. this is a bug.
160 note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
162 note: rustc 1.24.0-dev running on x86_64-unknown-linux-gnu
164 note: run with `RUST_BACKTRACE=1` for a backtrace
166 thread 'rustc' panicked at 'encountered error with `-Z treat_err_as_bug',
167 /home/user/rust/compiler/rustc_errors/src/lib.rs:411:12
168 note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose
171 (~~~ IRRELEVANT PART OF BACKTRACE REMOVED BY ME ~~~)
172 7: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'tcx>>
173 ::report_selection_error
174 at /home/user/rust/compiler/rustc_middle/src/traits/error_reporting.rs:823
175 8: rustc::traits::error_reporting::<impl rustc::infer::InferCtxt<'a, 'tcx>>
176 ::report_fulfillment_errors
177 at /home/user/rust/compiler/rustc_middle/src/traits/error_reporting.rs:160
178 at /home/user/rust/compiler/rustc_middle/src/traits/error_reporting.rs:112
179 9: rustc_typeck::check::FnCtxt::select_obligations_where_possible
180 at /home/user/rust/compiler/rustc_typeck/src/check/mod.rs:2192
181 (~~~ IRRELEVANT PART OF BACKTRACE REMOVED BY ME ~~~)
182 36: rustc_driver::run_compiler
183 at /home/user/rust/compiler/rustc_driver/src/lib.rs:253
186 Cool, now I have a backtrace for the error!
188 ## Getting logging output
190 The compiler uses the [`tracing`] crate for logging.
192 [`tracing`]: https://docs.rs/tracing
194 For details see [the guide section on tracing](./tracing.md)
196 ## Formatting Graphviz output (.dot files)
197 [formatting-graphviz-output]: #formatting-graphviz-output
199 Some compiler options for debugging specific features yield graphviz graphs -
200 e.g. the `#[rustc_mir(borrowck_graphviz_postflow="suffix.dot")]` attribute
201 dumps various borrow-checker dataflow graphs.
203 These all produce `.dot` files. To view these files, install graphviz (e.g.
204 `apt-get install graphviz`) and then run the following commands:
207 $ dot -T pdf maybe_init_suffix.dot > maybe_init_suffix.pdf
208 $ firefox maybe_init_suffix.pdf # Or your favorite pdf viewer
211 ## Viewing Spanview output (.html files)
212 [viewing-spanview-output]: #viewing-spanview-output
214 In addition to [graphviz output](#formatting-graphviz-output-dot-files), MIR debugging
215 flags include an option to generate a MIR representation called `Spanview` that
216 uses HTML to highlight code regions in the original source code and display
217 compiler metadata associated with each region.
218 [`-Z dump-mir-spanview`](./mir/debugging.md), for example, highlights spans
219 associated with each MIR `Statement`, `Terminator`, and/or `BasicBlock`.
221 These `.html` files use CSS features to dynamically expand spans obscured by
222 overlapping spans, and native tooltips (based on the HTML `title` attribute) to
223 reveal the actual MIR elements, as text.
225 To view these files, simply use a modern browser, or a CSS-capable HTML preview
226 feature in a modern IDE. (The default HTML preview pane in *VS Code* is known to
229 ## Narrowing (Bisecting) Regressions
231 The [cargo-bisect-rustc][bisect] tool can be used as a quick and easy way to
232 find exactly which PR caused a change in `rustc` behavior. It automatically
233 downloads `rustc` PR artifacts and tests them against a project you provide
234 until it finds the regression. You can then look at the PR to get more context
235 on *why* it was changed. See [this tutorial][bisect-tutorial] on how to use
238 [bisect]: https://github.com/rust-lang/cargo-bisect-rustc
239 [bisect-tutorial]: https://github.com/rust-lang/cargo-bisect-rustc/blob/master/TUTORIAL.md
241 ## Downloading Artifacts from Rust's CI
243 The [rustup-toolchain-install-master][rtim] tool by kennytm can be used to
244 download the artifacts produced by Rust's CI for a specific SHA1 -- this
245 basically corresponds to the successful landing of some PR -- and then sets
246 them up for your local use. This also works for artifacts produced by `@bors
247 try`. This is helpful when you want to examine the resulting build of a PR
248 without doing the build yourself.
250 [rtim]: https://github.com/kennytm/rustup-toolchain-install-master
252 ## Debugging type layouts
254 The (permanently) unstable `#[rustc_layout]` attribute can be used to dump
255 the [`Layout`] of the type it is attached to. For example:
258 #![feature(rustc_attrs)]
260 #[rustc_layout(debug)]
261 type T<'a> = &'a u32;
264 Will emit the following:
267 error: layout_of(&'a u32) = Layout {
275 valid_range: 1..=18446744073709551615,
285 valid_range: 1..=18446744073709551615,
289 align: AbiAndPrefAlign {
303 4 | type T<'a> = &'a u32;
304 | ^^^^^^^^^^^^^^^^^^^^^
306 error: aborting due to previous error
309 [`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/abi/struct.Layout.html