Skip to content

allow RUST_BACKTRACE=0 to act as if unset #32549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions man/rustc.1
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,15 @@ 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
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:
Expand Down
5 changes: 4 additions & 1 deletion src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/doc/book/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@ stack backtrace:
13: 0x0 - <unknown>
```

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 '<main>' 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
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,10 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
for note in &xs {
emitter.emit(None, &note[..], 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,
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/common/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions src/libtest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -399,7 +399,10 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {

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) {
Expand Down
10 changes: 10 additions & 0 deletions src/test/run-pass/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
25 changes: 17 additions & 8 deletions src/test/run-pass/multi-panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<unnamed>' 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 '<main>' panicked at")), Some(true));
assert_eq!(it.next(), None);
}

fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() > 1 && args[1] == "run_test" {
Expand All @@ -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 '<unnamed>' 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 '<main>' 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);
}
}