Auto merge of #2084 - rust-lang:silence, r=RalfJung
Add a command line flag to avoid printing to stdout and stderr This is practical for tests that don't actually care about the output and thus don't want it intermingled with miri's warnings, errors or ICEs fixes #2083
This commit is contained in:
commit
36c274aa38
7 changed files with 79 additions and 9 deletions
|
|
@ -286,6 +286,10 @@ environment variable:
|
|||
This can be used to find which parts of your program are executing slowly under Miri.
|
||||
The profile is written out to a file with the prefix `<name>`, and can be processed
|
||||
using the tools in the repository https://github.com/rust-lang/measureme.
|
||||
* `-Zmiri-mute-stdout-stderr` silently ignores all writes to stdout and stderr,
|
||||
but reports to the program that it did actually write. This is useful when you
|
||||
are not interested in the actual program's output, but only want to see miri's
|
||||
errors and warnings.
|
||||
* `-Zmiri-panic-on-unsupported` will makes some forms of unsupported functionality,
|
||||
such as FFI and unsupported syscalls, panic within the context of the emulated
|
||||
application instead of raising an error within the context of Miri (and halting
|
||||
|
|
|
|||
|
|
@ -384,6 +384,9 @@ fn main() {
|
|||
miri_config.tag_raw = true;
|
||||
miri_config.check_number_validity = true;
|
||||
}
|
||||
"-Zmiri-mute-stdout-stderr" => {
|
||||
miri_config.mute_stdout_stderr = true;
|
||||
}
|
||||
"-Zmiri-track-raw-pointers" => {
|
||||
eprintln!(
|
||||
"WARNING: -Zmiri-track-raw-pointers has been renamed to -Zmiri-tag-raw-pointers, the old name is deprecated."
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ pub struct MiriConfig {
|
|||
/// Whether to enforce "strict provenance" rules. Enabling this means int2ptr casts return
|
||||
/// pointers with an invalid provenance, i.e., not valid for any memory access.
|
||||
pub strict_provenance: bool,
|
||||
/// Whether to ignore any output by the program. This is helpful when debugging miri
|
||||
/// as its messages don't get intermingled with the program messages.
|
||||
pub mute_stdout_stderr: bool,
|
||||
}
|
||||
|
||||
impl Default for MiriConfig {
|
||||
|
|
@ -142,6 +145,7 @@ impl Default for MiriConfig {
|
|||
panic_on_unsupported: false,
|
||||
backtrace_style: BacktraceStyle::Short,
|
||||
strict_provenance: false,
|
||||
mute_stdout_stderr: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use rustc_span::symbol::{sym, Symbol};
|
|||
use rustc_target::abi::Size;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::*;
|
||||
use crate::{*, shims::posix::FileHandler};
|
||||
|
||||
// Some global facts about the emulated machine.
|
||||
pub const PAGE_SIZE: u64 = 4 * 1024; // FIXME: adjust to target architecture
|
||||
|
|
@ -291,6 +291,9 @@ pub struct Evaluator<'mir, 'tcx> {
|
|||
|
||||
/// Failure rate of compare_exchange_weak, between 0.0 and 1.0
|
||||
pub(crate) cmpxchg_weak_failure_rate: f64,
|
||||
|
||||
/// Corresponds to -Zmiri-mute-stdout-stderr and doesn't write the output but acts as if it succeeded.
|
||||
pub(crate) mute_stdout_stderr: bool,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
|
||||
|
|
@ -327,7 +330,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
|
|||
validate: config.validate,
|
||||
enforce_number_validity: config.check_number_validity,
|
||||
enforce_abi: config.check_abi,
|
||||
file_handler: Default::default(),
|
||||
file_handler: FileHandler::new(config.mute_stdout_stderr),
|
||||
dir_handler: Default::default(),
|
||||
time_anchor: Instant::now(),
|
||||
layouts,
|
||||
|
|
@ -344,6 +347,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
|
|||
tracked_alloc_ids: config.tracked_alloc_ids.clone(),
|
||||
check_alignment: config.check_alignment,
|
||||
cmpxchg_weak_failure_rate: config.cmpxchg_weak_failure_rate,
|
||||
mute_stdout_stderr: config.mute_stdout_stderr,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,22 +251,70 @@ impl FileDescriptor for io::Stderr {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DummyOutput;
|
||||
|
||||
impl FileDescriptor for DummyOutput {
|
||||
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> {
|
||||
throw_unsup_format!("stderr and stdout cannot be used as FileHandle");
|
||||
}
|
||||
|
||||
fn read<'tcx>(
|
||||
&mut self,
|
||||
_communicate_allowed: bool,
|
||||
_bytes: &mut [u8],
|
||||
) -> InterpResult<'tcx, io::Result<usize>> {
|
||||
throw_unsup_format!("cannot read from stderr or stdout");
|
||||
}
|
||||
|
||||
fn write<'tcx>(
|
||||
&self,
|
||||
_communicate_allowed: bool,
|
||||
bytes: &[u8],
|
||||
) -> InterpResult<'tcx, io::Result<usize>> {
|
||||
// We just don't write anything, but report to the user that we did.
|
||||
Ok(Ok(bytes.len()))
|
||||
}
|
||||
|
||||
fn seek<'tcx>(
|
||||
&mut self,
|
||||
_communicate_allowed: bool,
|
||||
_offset: SeekFrom,
|
||||
) -> InterpResult<'tcx, io::Result<u64>> {
|
||||
throw_unsup_format!("cannot seek on stderr or stdout");
|
||||
}
|
||||
|
||||
fn close<'tcx>(
|
||||
self: Box<Self>,
|
||||
_communicate_allowed: bool,
|
||||
) -> InterpResult<'tcx, io::Result<i32>> {
|
||||
throw_unsup_format!("stderr and stdout cannot be closed");
|
||||
}
|
||||
|
||||
fn dup<'tcx>(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
||||
Ok(Box::new(DummyOutput))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FileHandler {
|
||||
handles: BTreeMap<i32, Box<dyn FileDescriptor>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Default for FileHandler {
|
||||
fn default() -> Self {
|
||||
impl<'tcx> FileHandler {
|
||||
pub(crate) fn new(mute_stdout_stderr: bool) -> FileHandler {
|
||||
let mut handles: BTreeMap<_, Box<dyn FileDescriptor>> = BTreeMap::new();
|
||||
handles.insert(0i32, Box::new(io::stdin()));
|
||||
handles.insert(1i32, Box::new(io::stdout()));
|
||||
if mute_stdout_stderr {
|
||||
handles.insert(0i32, Box::new(DummyOutput));
|
||||
handles.insert(1i32, Box::new(DummyOutput));
|
||||
} else {
|
||||
handles.insert(0i32, Box::new(io::stdin()));
|
||||
handles.insert(1i32, Box::new(io::stdout()));
|
||||
}
|
||||
handles.insert(2i32, Box::new(io::stderr()));
|
||||
FileHandler { handles }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> FileHandler {
|
||||
fn insert_fd(&mut self, file_handle: Box<dyn FileDescriptor>) -> i32 {
|
||||
self.insert_fd_with_min_fd(file_handle, 0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
use std::io::{self, Write};
|
||||
|
||||
let buf_cont = this.read_bytes_ptr(buf, Size::from_bytes(u64::from(n)))?;
|
||||
let res = if handle == -11 {
|
||||
let res = if this.machine.mute_stdout_stderr {
|
||||
Ok(buf_cont.len())
|
||||
} else if handle == -11 {
|
||||
io::stdout().write(buf_cont)
|
||||
} else {
|
||||
io::stderr().write(buf_cont)
|
||||
|
|
|
|||
5
tests/run-pass/hide_stdout.rs
Normal file
5
tests/run-pass/hide_stdout.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// compile-flags: -Zmiri-mute-stdout-stderr
|
||||
|
||||
fn main() {
|
||||
println!("cake");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue