Skip to content

Commit 1fe925e

Browse files
authored
Merge branch 'master' into atomic-arith
2 parents 40b7502 + 75f667e commit 1fe925e

File tree

3 files changed

+72
-47
lines changed

3 files changed

+72
-47
lines changed

README.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Several `-Z` flags are relevant for miri:
114114

115115
Since the heart of Miri (the main interpreter engine) lives in rustc, working on
116116
Miri will often require using a locally built rustc. This includes getting a
117-
trace of the execution, as distributed rustc has `trace!` disabled.
117+
trace of the execution, as distributed rustc has `debug!` and `trace!` disabled.
118118

119119
The first-time setup for a local rustc looks as follows:
120120
```
@@ -130,14 +130,28 @@ rustup override set custom
130130
```
131131
The `build` step can take 30 minutes and more.
132132

133-
Now you can `cargo build` Miri, and you can `cargo test --tests`. (`--tests`
134-
is needed to skip doctests because we have not built rustdoc for your custom
135-
toolchain.) You can also set `RUST_LOG=rustc_mir::interpret=trace` as
136-
environment variable to get a step-by-step trace.
133+
Now you can `cargo build` Miri, and you can `cargo test` it. But the key point
134+
is, you can now run Miri with a trace of all execution steps:
135+
136+
```sh
137+
MIRI_LOG=debug cargo run tests/run-pass/vecs.rs
138+
```
139+
140+
Setting `MIRI_LOG` like this will configure logging for miri itself as well as
141+
the `rustc::mir::interpret` and `rustc_mir::interpret` modules in rustc. You
142+
can also do more targeted configuration, e.g. to debug the stacked borrows
143+
implementation:
144+
145+
```sh
146+
MIRI_LOG=miri::stacked_borrows=trace,rustc_mir::interpret=debug cargo run tests/run-pass/vecs.rs
147+
```
148+
149+
In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an
150+
evaluation error was originally created.
137151

138152
If you changed something in rustc and want to re-build, run
139153
```
140-
./x.py build src/rustc --keep-stage 0
154+
./x.py --keep-stage 0 build src/rustc
141155
```
142156
This avoids rebuilding the entire stage 0, which can save a lot of time.
143157

src/bin/miri.rs

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ extern crate log_settings;
1212
extern crate syntax;
1313
extern crate log;
1414

15+
use std::path::PathBuf;
16+
use std::str::FromStr;
17+
use std::env;
18+
1519
use rustc::session::Session;
1620
use rustc_metadata::cstore::CStore;
1721
use rustc_driver::{Compilation, CompilerCalls, RustcDefaultCalls};
@@ -21,7 +25,6 @@ use rustc::hir::{self, itemlikevisit};
2125
use rustc::ty::TyCtxt;
2226
use rustc_codegen_utils::codegen_backend::CodegenBackend;
2327
use syntax::ast;
24-
use std::path::PathBuf;
2528

2629
struct MiriCompilerCalls {
2730
default: Box<RustcDefaultCalls>,
@@ -105,6 +108,7 @@ fn after_analysis<'a, 'tcx>(
105108
state: &mut CompileState<'a, 'tcx>,
106109
validate: bool,
107110
) {
111+
init_late_loggers();
108112
state.session.abort_if_errors();
109113

110114
let tcx = state.tcx.unwrap();
@@ -148,42 +152,39 @@ fn after_analysis<'a, 'tcx>(
148152
}
149153
}
150154

151-
fn init_logger() {
152-
let format = |formatter: &mut env_logger::fmt::Formatter, record: &log::Record| {
153-
use std::io::Write;
154-
if record.level() == log::Level::Trace {
155-
// prepend frame number
156-
let indentation = log_settings::settings().indentation;
157-
writeln!(
158-
formatter,
159-
"{indentation}:{lvl}:{module}: {text}",
160-
lvl = record.level(),
161-
module = record.module_path().unwrap_or("<unknown module>"),
162-
indentation = indentation,
163-
text = record.args(),
164-
)
165-
} else {
166-
writeln!(
167-
formatter,
168-
"{lvl}:{module}: {text}",
169-
lvl = record.level(),
170-
module = record.module_path().unwrap_or("<unknown_module>"),
171-
text = record.args(),
172-
)
173-
}
174-
};
175-
176-
let mut builder = env_logger::Builder::new();
177-
builder.format(format).filter(
178-
None,
179-
log::LevelFilter::Info,
180-
);
181-
182-
if std::env::var("MIRI_LOG").is_ok() {
183-
builder.parse(&std::env::var("MIRI_LOG").unwrap());
155+
fn init_early_loggers() {
156+
// Notice that our `extern crate log` is NOT the same as rustc's! So we have to initialize
157+
// them both. We always initialize miri early.
158+
let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
159+
env_logger::init_from_env(env);
160+
// We only initialize rustc if the env var is set (so the user asked for it).
161+
// If it is not set, we avoid initializing now so that we can initialize
162+
// later with our custom settings, and NOT log anything for what happens before
163+
// miri gets started.
164+
if env::var("RUST_LOG").is_ok() {
165+
rustc_driver::init_rustc_env_logger();
184166
}
167+
}
185168

186-
builder.init();
169+
fn init_late_loggers() {
170+
// Initializing loggers right before we start evaluation. We overwrite the RUST_LOG
171+
// env var if it is not set, control it based on MIRI_LOG.
172+
if let Ok(var) = env::var("MIRI_LOG") {
173+
if env::var("RUST_LOG").is_err() {
174+
// We try to be a bit clever here: If MIRI_LOG is just a single level
175+
// used for everything, we only apply it to the parts of rustc that are
176+
// CTFE-related. Otherwise, we use it verbatim for RUST_LOG.
177+
// This way, if you set `MIRI_LOG=trace`, you get only the right parts of
178+
// rustc traced, but you can also do `MIRI_LOG=miri=trace,rustc_mir::interpret=debug`.
179+
if log::Level::from_str(&var).is_ok() {
180+
env::set_var("RUST_LOG",
181+
&format!("rustc::mir::interpret={0},rustc_mir::interpret={0}", var));
182+
} else {
183+
env::set_var("RUST_LOG", &var);
184+
}
185+
rustc_driver::init_rustc_env_logger();
186+
}
187+
}
187188
}
188189

189190
fn find_sysroot() -> String {
@@ -208,8 +209,7 @@ fn find_sysroot() -> String {
208209
}
209210

210211
fn main() {
211-
rustc_driver::init_rustc_env_logger();
212-
init_logger();
212+
init_early_loggers();
213213
let mut args: Vec<String> = std::env::args().collect();
214214

215215
let sysroot_flag = String::from("--sysroot");

src/lib.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
extern crate log;
77

88
// From rustc.
9+
extern crate syntax;
910
#[macro_use]
1011
extern crate rustc;
1112
extern crate rustc_data_structures;
1213
extern crate rustc_mir;
1314
extern crate rustc_target;
14-
extern crate syntax;
1515

1616
use std::collections::HashMap;
1717
use std::borrow::Cow;
18+
use std::env;
1819

1920
use rustc::ty::{self, Ty, TyCtxt, query::TyCtxtAt};
2021
use rustc::ty::layout::{TyLayout, LayoutOf, Size};
@@ -157,11 +158,21 @@ pub fn eval_main<'a, 'tcx: 'a>(
157158
) {
158159
let mut ecx = create_ecx(tcx, main_id, validate).expect("Couldn't create ecx");
159160

161+
// If MIRI_BACKTRACE is set and RUST_CTFE_BACKTRACE is not, set RUST_CTFE_BACKTRACE.
162+
// Do this late, so we really only apply this to miri's errors.
163+
if let Ok(var) = env::var("MIRI_BACKTRACE") {
164+
if env::var("RUST_CTFE_BACKTRACE") == Err(env::VarError::NotPresent) {
165+
env::set_var("RUST_CTFE_BACKTRACE", &var);
166+
}
167+
}
168+
169+
// Run! The main execution.
160170
let res: EvalResult = (|| {
161171
ecx.run()?;
162172
ecx.run_tls_dtors()
163173
})();
164174

175+
// Process the result.
165176
match res {
166177
Ok(()) => {
167178
let leaks = ecx.memory().leak_report();
@@ -173,7 +184,8 @@ pub fn eval_main<'a, 'tcx: 'a>(
173184
tcx.sess.err("the evaluated program leaked memory");
174185
}
175186
}
176-
Err(e) => {
187+
Err(mut e) => {
188+
e.print_backtrace();
177189
if let Some(frame) = ecx.stack().last() {
178190
let block = &frame.mir.basic_blocks()[frame.block];
179191
let span = if frame.stmt < block.statements.len() {
@@ -195,7 +207,6 @@ pub fn eval_main<'a, 'tcx: 'a>(
195207
ecx.tcx.sess.err(&e.to_string());
196208
}
197209

198-
/* Nice try, but with MIRI_BACKTRACE this shows 100s of backtraces.
199210
for (i, frame) in ecx.stack().iter().enumerate() {
200211
trace!("-------------------");
201212
trace!("Frame {}", i);
@@ -205,7 +216,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
205216
trace!(" local {}: {:?}", i, local);
206217
}
207218
}
208-
}*/
219+
}
209220
}
210221
}
211222
}

0 commit comments

Comments
 (0)