Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
134
third-party/vendor/backtrace/tests/current-exe-mismatch.rs
vendored
Normal file
134
third-party/vendor/backtrace/tests/current-exe-mismatch.rs
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
// rust-lang/rust#101913: when you run your program explicitly via `ld.so`,
|
||||
// `std::env::current_exe` will return the path of *that* program, and not
|
||||
// the Rust program itself.
|
||||
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
mod common;
|
||||
|
||||
fn main() {
|
||||
if std::env::var(VAR).is_err() {
|
||||
// the parent waits for the child; then we then handle either printing
|
||||
// "test result: ok", "test result: ignored", or panicking.
|
||||
match parent() {
|
||||
Ok(()) => {
|
||||
println!("test result: ok");
|
||||
}
|
||||
Err(EarlyExit::IgnoreTest(_)) => {
|
||||
println!("test result: ignored");
|
||||
}
|
||||
Err(EarlyExit::IoError(e)) => {
|
||||
println!("{} parent encoutered IoError: {:?}", file!(), e);
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// println!("{} running child", file!());
|
||||
child().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
const VAR: &str = "__THE_TEST_YOU_ARE_LUKE";
|
||||
|
||||
#[derive(Debug)]
|
||||
enum EarlyExit {
|
||||
IgnoreTest(String),
|
||||
IoError(std::io::Error),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for EarlyExit {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
EarlyExit::IoError(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn parent() -> Result<(), EarlyExit> {
|
||||
// If we cannot re-exec this test, there's no point in trying to do it.
|
||||
if common::cannot_reexec_the_test() {
|
||||
return Err(EarlyExit::IgnoreTest("(cannot reexec)".into()));
|
||||
}
|
||||
|
||||
let me = std::env::current_exe().unwrap();
|
||||
let ld_so = find_interpreter(&me)?;
|
||||
|
||||
// use interp to invoke current exe, yielding child test.
|
||||
//
|
||||
// (if you're curious what you might compare this against, you can try
|
||||
// swapping in the below definition for `result`, which is the easy case of
|
||||
// not using the ld.so interpreter directly that Rust handled fine even
|
||||
// prior to resolution of rust-lang/rust#101913.)
|
||||
//
|
||||
// let result = Command::new(me).env(VAR, "1").output()?;
|
||||
let result = Command::new(ld_so).env(VAR, "1").arg(&me).output().unwrap();
|
||||
|
||||
if result.status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
println!("stdout:\n{}", String::from_utf8_lossy(&result.stdout));
|
||||
println!("stderr:\n{}", String::from_utf8_lossy(&result.stderr));
|
||||
println!("code: {}", result.status);
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn child() -> Result<(), EarlyExit> {
|
||||
let bt = backtrace::Backtrace::new();
|
||||
println!("{:?}", bt);
|
||||
|
||||
let mut found_my_name = false;
|
||||
|
||||
let my_filename = file!();
|
||||
'frames: for frame in bt.frames() {
|
||||
let symbols = frame.symbols();
|
||||
if symbols.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
for sym in symbols {
|
||||
if let Some(filename) = sym.filename() {
|
||||
if filename.ends_with(my_filename) {
|
||||
// huzzah!
|
||||
found_my_name = true;
|
||||
break 'frames;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(found_my_name);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// we use the `readelf` command to extract the path to the interpreter requested
|
||||
// by our binary.
|
||||
//
|
||||
// if we cannot `readelf` for some reason, or if we fail to parse its output,
|
||||
// then we will just give up on this test (and not treat it as a test failure).
|
||||
fn find_interpreter(me: &Path) -> Result<PathBuf, EarlyExit> {
|
||||
let result = Command::new("readelf")
|
||||
.arg("-l")
|
||||
.arg(me)
|
||||
.output()
|
||||
.map_err(|_err| EarlyExit::IgnoreTest("readelf invocation failed".into()))?;
|
||||
if result.status.success() {
|
||||
let r = BufReader::new(&result.stdout[..]);
|
||||
for line in r.lines() {
|
||||
let line = line?;
|
||||
let line = line.trim();
|
||||
let prefix = "[Requesting program interpreter: ";
|
||||
if let Some((_, suffix)) = line.split_once(prefix) {
|
||||
if let Some((found_path, _)) = suffix.rsplit_once("]") {
|
||||
return Ok(found_path.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(EarlyExit::IgnoreTest(
|
||||
"could not find interpreter from readelf output".into(),
|
||||
))
|
||||
} else {
|
||||
Err(EarlyExit::IgnoreTest("readelf returned non-success".into()))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue