diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f721709b9f..10598e78ec5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,8 @@ which includes important information about what platform you're on, what version of Rust you're using, etc. Sometimes, a backtrace is helpful, and so including that is nice. To get -a backtrace, set the `RUST_BACKTRACE` environment variable. The easiest way +a backtrace, set the `RUST_BACKTRACE` environment variable to a value +other than `0`. The easiest way to do this is to invoke `rustc` like this: ```bash diff --git a/man/rustc.1 b/man/rustc.1 index 0b8b1559d90..a034e471b6e 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -268,7 +268,7 @@ the maximum number of threads used for this purpose. .TP \fBRUST_TEST_NOCAPTURE\fR -A synonym for the --nocapture flag. +If set to a value other than "0", a synonym for the --nocapture flag. .TP \fBRUST_MIN_STACK\fR @@ -276,7 +276,7 @@ Sets the minimum stack size for new threads. .TP \fBRUST_BACKTRACE\fR -If set, produces a backtrace in the output of a program which panics. +If set to a value different than "0", produces a backtrace in the output of a program which panics. .SH "EXAMPLES" To build an executable from a source file with a main function: diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 6c6a78a360b..787d77bc56c 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -263,7 +263,10 @@ pub fn test_opts(config: &Config) -> test::TestOpts { logfile: config.logfile.clone(), run_tests: true, bench_benchmarks: true, - nocapture: env::var("RUST_TEST_NOCAPTURE").is_ok(), + nocapture: match env::var("RUST_TEST_NOCAPTURE") { + Ok(val) => &val != "0", + Err(_) => false + }, color: test::AutoColor, } } diff --git a/src/doc/book/functions.md b/src/doc/book/functions.md index 31c9da3fada..8a2444323f1 100644 --- a/src/doc/book/functions.md +++ b/src/doc/book/functions.md @@ -246,6 +246,19 @@ stack backtrace: 13: 0x0 - ``` +If you need to override an already set `RUST_BACKTRACE`, +in cases when you cannot just unset the variable, +then set it to `0` to avoid getting a backtrace. +Any other value(even no value at all) turns on backtrace. + +```text +$ export RUST_BACKTRACE=1 +... +$ RUST_BACKTRACE=0 ./diverges +thread '
' panicked at 'This function never returns!', hello.rs:2 +note: Run with `RUST_BACKTRACE=1` for a backtrace. +``` + `RUST_BACKTRACE` also works with Cargo’s `run` command: ```text diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 516c55e1020..3444b770cc8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1059,7 +1059,10 @@ pub fn monitor(f: F) { for note in &xs { emitter.emit(None, ¬e[..], None, errors::Level::Note) } - if let None = env::var_os("RUST_BACKTRACE") { + if match env::var_os("RUST_BACKTRACE") { + Some(val) => &val != "0", + None => false, + } { emitter.emit(None, "run with `RUST_BACKTRACE=1` for a backtrace", None, diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs index b81fb3011c7..24e1a82a593 100644 --- a/src/libstd/sys/common/backtrace.rs +++ b/src/libstd/sys/common/backtrace.rs @@ -36,7 +36,7 @@ pub fn log_enabled() -> bool { } let val = match env::var_os("RUST_BACKTRACE") { - Some(..) => 2, + Some(x) => if &x == "0" { 1 } else { 2 }, None => 1, }; ENABLED.store(val, Ordering::SeqCst); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index e4d7697a71b..e7fe128a7ae 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -349,8 +349,8 @@ By default, all tests are run in parallel. This can be altered with the RUST_TEST_THREADS environment variable when running tests (set it to 1). All tests have their standard output and standard error captured by default. -This can be overridden with the --nocapture flag or the RUST_TEST_NOCAPTURE=1 -environment variable. Logging is not captured by default. +This can be overridden with the --nocapture flag or setting RUST_TEST_NOCAPTURE +environment variable to a value other than "0". Logging is not captured by default. Test Attributes: @@ -399,7 +399,10 @@ pub fn parse_opts(args: &[String]) -> Option { let mut nocapture = matches.opt_present("nocapture"); if !nocapture { - nocapture = env::var("RUST_TEST_NOCAPTURE").is_ok(); + nocapture = match env::var("RUST_TEST_NOCAPTURE") { + Ok(val) => &val != "0", + Err(_) => false + }; } let color = match matches.opt_str("color").as_ref().map(|s| &**s) { diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 36cac8f50a8..a2108ff041d 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -86,6 +86,16 @@ fn runtest(me: &str) { assert!(!s.contains("stack backtrace") && !s.contains(&expected("foo")), "bad output2: {}", s); + // Make sure the stack trace is *not* printed + // (RUST_BACKTRACE=0 acts as if it were unset from our own environment, + // in case developer is running `make check` with it set.) + let p = template(me).arg("fail").env("RUST_BACKTRACE","0").spawn().unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(!out.status.success()); + let s = str::from_utf8(&out.stderr).unwrap(); + assert!(!s.contains("stack backtrace") && !s.contains(" - foo"), + "bad output3: {}", s); + // Make sure a stack trace is printed let p = template(me).arg("double-fail").spawn().unwrap(); let out = p.wait_with_output().unwrap(); diff --git a/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs index 6a0d7278b5e..8e0b14128c8 100644 --- a/src/test/run-pass/multi-panic.rs +++ b/src/test/run-pass/multi-panic.rs @@ -8,6 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn check_for_no_backtrace(test: std::process::Output) { + assert!(!test.status.success()); + let err = String::from_utf8_lossy(&test.stderr); + let mut it = err.lines(); + + assert_eq!(it.next().map(|l| l.starts_with("thread '' panicked at")), Some(true)); + assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` for a backtrace.")); + assert_eq!(it.next().map(|l| l.starts_with("thread '
' panicked at")), Some(true)); + assert_eq!(it.next(), None); +} + fn main() { let args: Vec = std::env::args().collect(); if args.len() > 1 && args[1] == "run_test" { @@ -21,13 +32,11 @@ fn main() { .env_remove("RUST_BACKTRACE") .output() .unwrap(); - assert!(!test.status.success()); - let err = String::from_utf8_lossy(&test.stderr); - let mut it = err.lines(); - - assert_eq!(it.next().map(|l| l.starts_with("thread '' panicked at")), Some(true)); - assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` for a backtrace.")); - assert_eq!(it.next().map(|l| l.starts_with("thread '
' panicked at")), Some(true)); - assert_eq!(it.next(), None); + check_for_no_backtrace(test); + let test = std::process::Command::new(&args[0]).arg("run_test") + .env("RUST_BACKTRACE","0") + .output() + .unwrap(); + check_for_no_backtrace(test); } }