Skip to content

Commit 4d4855c

Browse files
committed
Add a command line flag to avoid printing to stdout and stderr
1 parent 3ac7ca4 commit 4d4855c

File tree

5 files changed

+68
-8
lines changed

5 files changed

+68
-8
lines changed

src/bin/miri.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ fn main() {
374374
miri_config.tag_raw = true;
375375
miri_config.check_number_validity = true;
376376
}
377+
"-Zmiri-drop-stdout-stderr" => {
378+
miri_config.drop_stdout_stderr = true;
379+
}
377380
"-Zmiri-track-raw-pointers" => {
378381
eprintln!(
379382
"WARNING: -Zmiri-track-raw-pointers has been renamed to -Zmiri-tag-raw-pointers, the old name is deprecated."

src/eval.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ pub struct MiriConfig {
116116
/// Whether to enforce "strict provenance" rules. Enabling this means int2ptr casts return
117117
/// pointers with an invalid provenance, i.e., not valid for any memory access.
118118
pub strict_provenance: bool,
119+
/// Whether to ignore any output by the program. This is helpful when debugging miri
120+
/// as its messages don't get intermingled with the program messages.
121+
pub drop_stdout_stderr: bool,
119122
}
120123

121124
impl Default for MiriConfig {
@@ -142,6 +145,7 @@ impl Default for MiriConfig {
142145
panic_on_unsupported: false,
143146
backtrace_style: BacktraceStyle::Short,
144147
strict_provenance: false,
148+
drop_stdout_stderr: false,
145149
}
146150
}
147151
}

src/machine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_span::symbol::{sym, Symbol};
2828
use rustc_target::abi::Size;
2929
use rustc_target::spec::abi::Abi;
3030

31-
use crate::*;
31+
use crate::{*, shims::posix::FileHandler};
3232

3333
// Some global facts about the emulated machine.
3434
pub const PAGE_SIZE: u64 = 4 * 1024; // FIXME: adjust to target architecture
@@ -327,7 +327,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
327327
validate: config.validate,
328328
enforce_number_validity: config.check_number_validity,
329329
enforce_abi: config.check_abi,
330-
file_handler: Default::default(),
330+
file_handler: FileHandler::new(config.drop_stdout_stderr),
331331
dir_handler: Default::default(),
332332
time_anchor: Instant::now(),
333333
layouts,

src/shims/posix/fs.rs

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,22 +251,70 @@ impl FileDescriptor for io::Stderr {
251251
}
252252
}
253253

254+
#[derive(Debug)]
255+
struct DevNull;
256+
257+
impl FileDescriptor for DevNull {
258+
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> {
259+
throw_unsup_format!("/dev/null cannot be used as FileHandle");
260+
}
261+
262+
fn read<'tcx>(
263+
&mut self,
264+
_communicate_allowed: bool,
265+
_bytes: &mut [u8],
266+
) -> InterpResult<'tcx, io::Result<usize>> {
267+
throw_unsup_format!("cannot read from /dev/null");
268+
}
269+
270+
fn write<'tcx>(
271+
&self,
272+
_communicate_allowed: bool,
273+
bytes: &[u8],
274+
) -> InterpResult<'tcx, io::Result<usize>> {
275+
// We just don't write anything
276+
Ok(Ok(bytes.len()))
277+
}
278+
279+
fn seek<'tcx>(
280+
&mut self,
281+
_communicate_allowed: bool,
282+
_offset: SeekFrom,
283+
) -> InterpResult<'tcx, io::Result<u64>> {
284+
throw_unsup_format!("cannot seek on /dev/null");
285+
}
286+
287+
fn close<'tcx>(
288+
self: Box<Self>,
289+
_communicate_allowed: bool,
290+
) -> InterpResult<'tcx, io::Result<i32>> {
291+
throw_unsup_format!("/dev/null cannot be closed");
292+
}
293+
294+
fn dup<'tcx>(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
295+
Ok(Box::new(DevNull))
296+
}
297+
}
298+
254299
#[derive(Debug)]
255300
pub struct FileHandler {
256301
handles: BTreeMap<i32, Box<dyn FileDescriptor>>,
257302
}
258303

259-
impl<'tcx> Default for FileHandler {
260-
fn default() -> Self {
304+
impl<'tcx> FileHandler {
305+
pub(crate) fn new(drop_stdout_stderr: bool) -> FileHandler {
261306
let mut handles: BTreeMap<_, Box<dyn FileDescriptor>> = BTreeMap::new();
262-
handles.insert(0i32, Box::new(io::stdin()));
263-
handles.insert(1i32, Box::new(io::stdout()));
307+
if drop_stdout_stderr {
308+
handles.insert(0i32, Box::new(DevNull));
309+
handles.insert(1i32, Box::new(DevNull));
310+
} else {
311+
handles.insert(0i32, Box::new(io::stdin()));
312+
handles.insert(1i32, Box::new(io::stdout()));
313+
}
264314
handles.insert(2i32, Box::new(io::stderr()));
265315
FileHandler { handles }
266316
}
267-
}
268317

269-
impl<'tcx> FileHandler {
270318
fn insert_fd(&mut self, file_handle: Box<dyn FileDescriptor>) -> i32 {
271319
self.insert_fd_with_min_fd(file_handle, 0)
272320
}

tests/run-pass/hide_stdout.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// compile-flags: -Zmiri-drop-stdout-stderr
2+
3+
fn main() {
4+
println!("cake");
5+
}

0 commit comments

Comments
 (0)