1
- The compiler has a lot of [ ` debug! ` ] calls, which print out logging information
1
+ # Using tracing to debug the compiler
2
+
3
+ <!-- toc -->
4
+
5
+ The compiler has a lot of [ ` debug! ` ] (or ` trace! ` ) calls, which print out logging information
2
6
at many points. These are very useful to at least narrow down the location of
3
7
a bug if not to find it entirely, or just to orient yourself as to why the
4
8
compiler is doing a particular thing.
5
9
6
10
[ `debug!` ] : https://docs.rs/tracing/0.1/tracing/macro.debug.html
7
11
8
12
To see the logs, you need to set the ` RUSTC_LOG ` environment variable to your
9
- log filter. Your log filter can be just ` debug ` to get all ` debug! ` output and
13
+ log filter.
14
+
15
+ ## Function level filters
16
+
17
+ Lots of functions in rustc are annotated with
18
+
19
+ ```
20
+ #[instrument(level = "debug", skip(self))]
21
+ fn foo(&self, bar: Type) {}
22
+ ```
23
+
24
+ which allows you to use
25
+
26
+ ```
27
+ RUSTC_LOG=[foo]
28
+ ```
29
+
30
+ to do the following all at once
31
+
32
+ * log all function calls to ` foo `
33
+ * log the arguments (except for those in the ` skip ` list)
34
+ * log everything (from anywhere else in the compiler) until the function returns
35
+
36
+ ### I don't want everything
37
+
38
+ Depending on the scope of the function, you may not want to log everything in its body.
39
+ As an example: the ` do_mir_borrowck ` function will dump hundreds of lines even for trivial
40
+ code being borrowchecked.
41
+
42
+ Since you can combine all filters, you can add a crate/module path, e.g.
43
+
44
+ ```
45
+ RUSTC_LOG=rustc_borrowck[do_mir_borrowck]
46
+ ```
47
+
48
+ ### I don't want all calls
49
+
50
+ If you are compiling libcore, you likely don't want * all* borrowck dumps, but only one
51
+ for a specific function. You can filter function calls by their arguments by regexing them.
52
+
53
+ ```
54
+ RUSTC_LOG=[do_mir_borrowck{id=\.\*from_utf8_unchecked\.\*}]
55
+ ```
56
+
57
+ will only give you the logs of borrowchecking ` from_utf8_unchecked ` . Note that you will
58
+ still get a short message per ignored ` do_mir_borrowck ` , but none of the things inside those
59
+ calls. This helps you in looking through the calls that are happening and helps you adjust
60
+ your regex if you mistyped it.
61
+
62
+ ## Broad module level filters
63
+
64
+ You can also use filters similar to the ` log ` crate's filters, which will enable
65
+ everything within a specific module. This is often too verbose and too unstructured,
66
+ so it is recommended to use function level filters.
67
+
68
+ Your log filter can be just ` debug ` to get all ` debug! ` output and
10
69
higher (e.g., it will also include ` info! ` ), or ` path::to::module ` to get * all*
11
70
output (which will include ` trace! ` ) from a particular module, or
12
71
` path::to::module=debug ` to get ` debug! ` output and higher from a particular
@@ -69,7 +128,7 @@ $ RUSTDOC_LOG=info rustdoc +stage1 my-file.rs
69
128
$ RUSTDOC_LOG=rustdoc=debug rustdoc +stage1 my-file.rs
70
129
```
71
130
72
- ### Log colors
131
+ ## Log colors
73
132
74
133
By default, rustc (and other tools, like rustdoc and Miri) will be smart about
75
134
when to use ANSI colors in the log output. If they are outputting to a terminal,
@@ -94,7 +153,7 @@ Note that `MIRI_LOG_COLOR` will only color logs that come from Miri, not logs
94
153
from rustc functions that Miri calls. Use ` RUSTC_LOG_COLOR ` to color logs from
95
154
rustc.
96
155
97
- ### How to keep or remove ` debug! ` and ` trace! ` calls from the resulting binary
156
+ ## How to keep or remove ` debug! ` and ` trace! ` calls from the resulting binary
98
157
99
158
While calls to ` error! ` , ` warn! ` and ` info! ` are included in every build of the compiler,
100
159
calls to ` debug! ` and ` trace! ` are only included in the program if
@@ -104,30 +163,32 @@ if you run the compiler with `RUSTC_LOG=rustc rustc some.rs` and only see
104
163
` INFO ` logs, make sure that ` debug-logging=true ` is turned on in your
105
164
config.toml.
106
165
107
- ### Logging etiquette and conventions
166
+ ## Logging etiquette and conventions
108
167
109
168
Because calls to ` debug! ` are removed by default, in most cases, don't worry
110
169
about adding "unnecessary" calls to ` debug! ` and leaving them in code you
111
170
commit - they won't slow down the performance of what we ship, and if they
112
171
helped you pinning down a bug, they will probably help someone else with a
113
172
different one.
114
173
115
- A loosely followed convention is to use ` debug!("foo(...)") ` at the _ start_ of
116
- a function ` foo ` and ` debug!("foo: ...") ` _ within_ the function. Another
117
- loosely followed convention is to use the ` {:?} ` format specifier for debug
118
- logs.
174
+ It may be preferrable to use ` trace! ` over ` debug! ` for very noisy logs.
175
+
176
+ A loosely followed convention is to use ` #[instrument(level = "debug")] ` in
177
+ favour of ` debug!("foo(...)") ` at the start of a function ` foo ` .
178
+ Within functions, prefer ` debug!(?variable.field) ` over ` debug!("xyz = {:?}", variable.field) `
179
+ and ` debug!(bar = ?var.method(arg)) ` over ` debug!("bar = {:?}", var.method(arg)) ` .
119
180
120
181
One thing to be ** careful** of is ** expensive** operations in logs.
121
182
122
183
If in the module ` rustc::foo ` you have a statement
123
184
124
185
``` Rust
125
- debug! (" {:?} " , random_operation (tcx ));
186
+ debug! (x = ? random_operation (tcx ));
126
187
```
127
188
128
189
Then if someone runs a debug ` rustc ` with ` RUSTC_LOG=rustc::bar ` , then
129
190
` random_operation() ` will run.
130
191
131
192
This means that you should not put anything too expensive or likely to crash
132
193
there - that would annoy anyone who wants to use logging for their own module.
133
- No-one will know it until someone tries to use logging to find * another* bug.
194
+ No-one will know it until someone tries to use logging to find * another* bug.
0 commit comments