Use MIRI_ env vars to set RUST_ ones

This means we can do `MIRI_LOG=debug cargo run` and get something reasonable,
even if cargo has to build some dependencies first.
This commit is contained in:
Ralf Jung 2018-10-31 10:09:55 +01:00
parent f0c1f18314
commit eb153810e3
2 changed files with 41 additions and 38 deletions

View file

@ -12,6 +12,9 @@ extern crate log_settings;
extern crate syntax;
extern crate log;
use std::path::PathBuf;
use std::env;
use rustc::session::Session;
use rustc_metadata::cstore::CStore;
use rustc_driver::{Compilation, CompilerCalls, RustcDefaultCalls};
@ -21,7 +24,6 @@ use rustc::hir::{self, itemlikevisit};
use rustc::ty::TyCtxt;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use syntax::ast;
use std::path::PathBuf;
struct MiriCompilerCalls {
default: Box<RustcDefaultCalls>,
@ -148,42 +150,31 @@ fn after_analysis<'a, 'tcx>(
}
}
fn init_logger() {
let format = |formatter: &mut env_logger::fmt::Formatter, record: &log::Record| {
use std::io::Write;
if record.level() == log::Level::Trace {
// prepend frame number
let indentation = log_settings::settings().indentation;
writeln!(
formatter,
"{indentation}:{lvl}:{module}: {text}",
lvl = record.level(),
module = record.module_path().unwrap_or("<unknown module>"),
indentation = indentation,
text = record.args(),
)
} else {
writeln!(
formatter,
"{lvl}:{module}: {text}",
lvl = record.level(),
module = record.module_path().unwrap_or("<unknown_module>"),
text = record.args(),
)
fn init_loggers() {
// Notice that our `extern crate log` is NOT the same as rustc's! So we have to initialize
// them both.
// First, miri.
let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
env_logger::init_from_env(env);
// Now, change the RUST_LOG env var to control rustc's logger.
// If MIRI_LOG is set and RUST_LOG is not, set RUST_LOG.
if let Ok(var) = env::var("MIRI_LOG") {
if env::var("RUST_LOG") == Err(env::VarError::NotPresent) {
// We try to be a bit clever here: If MIRI_LOG is just a single level
// used for everything, we only apply it to the parts of rustc that are
// CTFE-related. Only if MIRI_LOG contains `module=level`, we just
// use the same value for RUST_LOG.
// This way, if you set `MIRI_LOG=trace`, you get only the right parts of
// rustc traced, but you can also do `MIRI_LOG=miri=trace,rustc_mir::interpret=debug`.
if var.contains('=') {
env::set_var("RUST_LOG", &var);
} else {
env::set_var("RUST_LOG",
&format!("rustc::mir::interpret={0},rustc_mir::interpret={0}", var));
}
}
};
let mut builder = env_logger::Builder::new();
builder.format(format).filter(
None,
log::LevelFilter::Info,
);
if std::env::var("MIRI_LOG").is_ok() {
builder.parse(&std::env::var("MIRI_LOG").unwrap());
}
builder.init();
rustc_driver::init_rustc_env_logger();
}
fn find_sysroot() -> String {
@ -208,8 +199,7 @@ fn find_sysroot() -> String {
}
fn main() {
rustc_driver::init_rustc_env_logger();
init_logger();
init_loggers();
let mut args: Vec<String> = std::env::args().collect();
let sysroot_flag = String::from("--sysroot");

View file

@ -11,10 +11,12 @@ extern crate rustc;
extern crate rustc_data_structures;
extern crate rustc_mir;
extern crate rustc_target;
extern crate rustc_driver;
extern crate syntax;
use std::collections::HashMap;
use std::borrow::Cow;
use std::env;
use rustc::ty::{self, Ty, TyCtxt, query::TyCtxtAt};
use rustc::ty::layout::{TyLayout, LayoutOf, Size};
@ -157,11 +159,21 @@ pub fn eval_main<'a, 'tcx: 'a>(
) {
let mut ecx = create_ecx(tcx, main_id, validate).expect("Couldn't create ecx");
// If MIRI_BACKTRACE is set and RUST_CTFE_BACKTRACE is not, set RUST_CTFE_BACKTRACE.
// Do this late, so we really only apply this to miri's errors.
if let Ok(var) = env::var("MIRI_BACKTRACE") {
if env::var("RUST_CTFE_BACKTRACE") == Err(env::VarError::NotPresent) {
env::set_var("RUST_CTFE_BACKTRACE", &var);
}
}
// Run! The main execution.
let res: EvalResult = (|| {
ecx.run()?;
ecx.run_tls_dtors()
})();
// Process the result.
match res {
Ok(()) => {
let leaks = ecx.memory().leak_report();
@ -173,7 +185,8 @@ pub fn eval_main<'a, 'tcx: 'a>(
tcx.sess.err("the evaluated program leaked memory");
}
}
Err(e) => {
Err(mut e) => {
e.print_backtrace();
if let Some(frame) = ecx.stack().last() {
let block = &frame.mir.basic_blocks()[frame.block];
let span = if frame.stmt < block.statements.len() {