mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	 d89500843c
			
		
	
	
		d89500843c
		
	
	
	
	
		
			
			- Move super-fast-paren-parsing test into ui/parser - Move stmt_expr_attrs test into ui/feature-gates - Move macro tests into ui/macros - Move global_asm tests into ui/asm - Move env tests into ui/process - Move xcrate tests into ui/cross-crate - Move unop tests into ui/unop - Move backtrace tests into ui/backtrace - Move check-static tests into ui/statics - Move expr tests into ui/expr - Move optimization fuel tests into ui/fuel - Move ffi attribute tests into ui/ffi-attrs - Move suggestion tests into ui/suggestions - Move main tests into ui/fn-main - Move lint tests into ui/lint - Move repr tests into ui/repr - Move intrinsics tests into ui/intrinsics - Move tool lint tests into ui/tool-attributes - Move return tests into ui/return - Move pattern tests into ui/patttern - Move range tests into ui/range - Move foreign-fn tests into ui/foreign - Move orphan-check tests into ui/coherence - Move inference tests into ui/inference - Reduce ROOT_ENTRY_LIMIT
		
			
				
	
	
		
			138 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //@ run-pass
 | |
| //@ ignore-android FIXME #17520
 | |
| //@ ignore-wasm32 spawning processes is not supported
 | |
| //@ ignore-openbsd no support for libbacktrace without filename
 | |
| //@ ignore-sgx no processes
 | |
| //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test
 | |
| //@ ignore-fuchsia Backtraces not symbolized
 | |
| //@ compile-flags:-g
 | |
| //@ compile-flags:-Cstrip=none
 | |
| 
 | |
| use std::env;
 | |
| use std::process::{Command, Stdio};
 | |
| use std::str;
 | |
| 
 | |
| #[inline(never)]
 | |
| fn foo() {
 | |
|     let _v = vec![1, 2, 3];
 | |
|     if env::var_os("IS_TEST").is_some() {
 | |
|         panic!()
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[inline(never)]
 | |
| fn double() {
 | |
|     struct Double;
 | |
| 
 | |
|     impl Drop for Double {
 | |
|         fn drop(&mut self) { panic!("twice") }
 | |
|     }
 | |
| 
 | |
|     let _d = Double;
 | |
| 
 | |
|     panic!("once");
 | |
| }
 | |
| 
 | |
| fn template(me: &str) -> Command {
 | |
|     let mut m = Command::new(me);
 | |
|     m.env("IS_TEST", "1")
 | |
|      .stdout(Stdio::piped())
 | |
|      .stderr(Stdio::piped());
 | |
|     return m;
 | |
| }
 | |
| 
 | |
| fn expected(fn_name: &str) -> String {
 | |
|     format!(" backtrace::{}", fn_name)
 | |
| }
 | |
| 
 | |
| #[cfg(not(panic = "abort"))]
 | |
| fn contains_verbose_expected(s: &str, fn_name: &str) -> bool {
 | |
|     // HACK(eddyb) work around the fact that verbosely demangled stack traces
 | |
|     // (from `RUST_BACKTRACE=full`, or, as is the case here, panic-in-panic)
 | |
|     // may contain symbols with hashes in them, i.e. `backtrace[...]::`.
 | |
|     let prefix = " backtrace";
 | |
|     let suffix = &format!("::{}", fn_name);
 | |
|     s.match_indices(prefix).any(|(i, _)| {
 | |
|         s[i + prefix.len()..]
 | |
|             .trim_start_matches('[')
 | |
|             .trim_start_matches(char::is_alphanumeric)
 | |
|             .trim_start_matches(']')
 | |
|             .starts_with(suffix)
 | |
|     })
 | |
| }
 | |
| 
 | |
| fn runtest(me: &str) {
 | |
|     // Make sure that the stack trace is printed
 | |
|     let p = template(me).arg("fail").env("RUST_BACKTRACE", "1").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(&expected("foo")),
 | |
|             "bad output: {}", s);
 | |
|     assert!(s.contains(" 0:"), "the frame number should start at 0");
 | |
| 
 | |
|     // Make sure the stack trace is *not* printed
 | |
|     // (Remove RUST_BACKTRACE from our own environment, in case developer
 | |
|     // is running `make check` with it on.)
 | |
|     let p = template(me).arg("fail").env_remove("RUST_BACKTRACE").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(&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);
 | |
| 
 | |
|     #[cfg(not(panic = "abort"))]
 | |
|     {
 | |
|         // Make sure a stack trace is printed
 | |
|         let p = template(me).arg("double-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();
 | |
|         // loosened the following from double::h to double:: due to
 | |
|         // spurious failures on mac, 32bit, optimized
 | |
|         assert!(
 | |
|             s.contains("stack backtrace") &&
 | |
|                 s.contains("panic in a destructor during cleanup") &&
 | |
|                 contains_verbose_expected(s, "double"),
 | |
|             "bad output3: {}", s
 | |
|         );
 | |
|         // Make sure it's only one stack trace.
 | |
|         assert_eq!(s.split("stack backtrace").count(), 2);
 | |
| 
 | |
|         // Make sure a stack trace isn't printed too many times
 | |
|         // even with RUST_BACKTRACE=1. It should be printed twice.
 | |
|         let p = template(me).arg("double-fail")
 | |
|                                     .env("RUST_BACKTRACE", "1").spawn().unwrap();
 | |
|         let out = p.wait_with_output().unwrap();
 | |
|         assert!(!out.status.success());
 | |
|         let s = str::from_utf8(&out.stderr).unwrap();
 | |
|         let mut i = 0;
 | |
|         for _ in 0..2 {
 | |
|             i += s[i + 10..].find("stack backtrace").unwrap() + 10;
 | |
|         }
 | |
|         assert!(s[i + 10..].find("stack backtrace").is_none(),
 | |
|                 "bad output4: {}", s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| fn main() {
 | |
|     let args: Vec<String> = env::args().collect();
 | |
|     if args.len() >= 2 && args[1] == "fail" {
 | |
|         foo();
 | |
|     } else if args.len() >= 2 && args[1] == "double-fail" {
 | |
|         double();
 | |
|     } else {
 | |
|         runtest(&args[0]);
 | |
|     }
 | |
| }
 |