|
| 1 | +# Debugging bootstrap |
| 2 | + |
| 3 | +> FIXME: this page could be expanded |
| 4 | +
|
| 5 | +## `tracing` in bootstrap |
| 6 | + |
| 7 | +Bootstrap has conditional [`tracing`][tracing] setup to provide structured logging. |
| 8 | + |
| 9 | +[tracing]: https://docs.rs/tracing/0.1.41/tracing/index.html |
| 10 | + |
| 11 | +### Enabling `tracing` output |
| 12 | + |
| 13 | +Bootstrap will conditionally enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set. |
| 14 | + |
| 15 | +Example usage: |
| 16 | + |
| 17 | +```bash |
| 18 | +$ BOOTSTRAP_TRACING=TRACE ./x build library --stage 1 |
| 19 | +``` |
| 20 | + |
| 21 | +Example output[^experimental]: |
| 22 | + |
| 23 | + |
| 24 | + |
| 25 | +[^experimental]: This shows what's *possible* with the infra in an experimental implementation. |
| 26 | + |
| 27 | +The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output. |
| 28 | + |
| 29 | +[tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html |
| 30 | + |
| 31 | +### Using `tracing` in bootstrap |
| 32 | + |
| 33 | +Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples: |
| 34 | + |
| 35 | +```rs |
| 36 | +#[cfg(feature = "tracing")] |
| 37 | +use tracing::{instrument, trace}; |
| 38 | + |
| 39 | +struct Foo; |
| 40 | + |
| 41 | +impl Step for Foo { |
| 42 | + type Output = (); |
| 43 | + |
| 44 | + #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Foo::should_run", skip_all))] |
| 45 | + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
| 46 | + #[cfg(feature = "tracing")] |
| 47 | + trace!(?run, "entered Foo::should_run"); |
| 48 | + |
| 49 | + todo!() |
| 50 | + } |
| 51 | + |
| 52 | + #[cfg_attr( |
| 53 | + feature = "tracing", |
| 54 | + instrument( |
| 55 | + level = "trace", |
| 56 | + name = "Foo::run", |
| 57 | + skip_all, |
| 58 | + fields(compiler = ?builder.compiler), |
| 59 | + ), |
| 60 | + )] |
| 61 | + fn run(self, builder: &Builder<'_>) -> Self::Output { |
| 62 | + #[cfg(feature = "tracing")] |
| 63 | + trace!(?run, "entered Foo::run"); |
| 64 | + |
| 65 | + todo!() |
| 66 | + } |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +For `#[instrument]`, it's recommended to: |
| 71 | + |
| 72 | +- Gate it behind `trace` level for fine-granularity, possibly `debug` level for core functions. |
| 73 | +- Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps. |
| 74 | +- Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled. |
| 75 | + |
| 76 | +### Enabling `tracing` bootstrap feature in rust-analyzer |
| 77 | + |
| 78 | +You can adjust your `settings.json`'s `rust-analyzer.check.overrideCommand` and `rust-analyzer.cargo.buildScripts.overrideCommand` if you want to also enable `logging` cargo feature by default in your editor. This is mostly useful if you want proper r-a completions and such when working on bootstrap itself. |
| 79 | + |
| 80 | +```json |
| 81 | +"rust-analyzer.check.overrideCommand": [ |
| 82 | + "BOOTSTRAP_TRACING=1", // <- BOOTSTRAP_TRACING=1 won't enable tracing filter, but it will activate bootstrap's `tracing` feature |
| 83 | + "python3", |
| 84 | + "x.py", |
| 85 | + "check", |
| 86 | + "--json-output", |
| 87 | + "--build-dir=build-rust-analyzer" |
| 88 | +], |
| 89 | +``` |
| 90 | + |
| 91 | +```json |
| 92 | +"rust-analyzer.cargo.buildScripts.overrideCommand": [ |
| 93 | + "BOOTSTRAP_TRACING=1", // <- note this |
| 94 | + "python3", |
| 95 | + "x.py", |
| 96 | + "check", |
| 97 | + "--json-output", |
| 98 | + "--build-dir=build-rust-analyzer" |
| 99 | +], |
| 100 | +``` |
0 commit comments