use std::env::current_exe;
use std::env::temp_dir;
use std::env::var_os;
use std::fs::read_to_string;
use std::fs::remove_file;
use std::io::ErrorKind;
use std::os::unix::process::ExitStatusExt;
use std::process::Command;
use libc::SIGQUIT;
use coredump::register_panic_handler;
const CHILD_MARKER: &str = "PANICING_CHILD";
#[cfg(not(target_os = "linux"))]
compile_error!("only Linux is supported currently");
#[test]
#[cfg(target_os = "linux")]
fn dump_core() {
if var_os(CHILD_MARKER).is_none() {
let tmp_dir = temp_dir();
let core_pattern = read_to_string("/proc/sys/kernel/core_pattern").unwrap();
if core_pattern.starts_with('|') {
return
}
let core_file = tmp_dir.join(core_pattern.trim_end());
match remove_file(&core_file) {
Ok(()) => (),
Err(ref err) if err.kind() == ErrorKind::NotFound => (),
Err(err) => panic!("unexpected error: {}", err),
};
let rc = Command::new(current_exe().unwrap())
.env_clear()
.env(CHILD_MARKER, "true")
.status()
.unwrap();
assert!(!rc.success());
assert_eq!(rc.signal().unwrap(), SIGQUIT);
assert!(
core_file.exists(),
"core file {} does not exist",
core_file.display(),
);
let _ = remove_file(&core_file);
} else {
register_panic_handler().unwrap();
panic!("induced panic");
}
}