diff --git a/aya-log-common/src/lib.rs b/aya-log-common/src/lib.rs index f6cb3517..472090ee 100644 --- a/aya-log-common/src/lib.rs +++ b/aya-log-common/src/lib.rs @@ -178,7 +178,7 @@ pub trait WriteToBuf { macro_rules! impl_write_to_buf { ($type:ident, $arg_type:expr) => { impl WriteToBuf for $type { - // This need not be inlined because the return value is Result where N is + // This need not be inlined because the return value is Option where N is // mem::size_of<$type>, which is a compile-time constant. #[inline(never)] fn write(self, buf: &mut [u8]) -> Option { @@ -204,7 +204,7 @@ impl_write_to_buf!(f32, Argument::F32); impl_write_to_buf!(f64, Argument::F64); impl WriteToBuf for [u8; 16] { - // This need not be inlined because the return value is Result where N is 16, which is a + // This need not be inlined because the return value is Option where N is 16, which is a // compile-time constant. #[inline(never)] fn write(self, buf: &mut [u8]) -> Option { @@ -213,7 +213,7 @@ impl WriteToBuf for [u8; 16] { } impl WriteToBuf for [u16; 8] { - // This need not be inlined because the return value is Result where N is 16, which is a + // This need not be inlined because the return value is Option where N is 16, which is a // compile-time constant. #[inline(never)] fn write(self, buf: &mut [u8]) -> Option { @@ -223,7 +223,7 @@ impl WriteToBuf for [u16; 8] { } impl WriteToBuf for [u8; 6] { - // This need not be inlined because the return value is Result where N is 6, which is a + // This need not be inlined because the return value is Option where N is 6, which is a // compile-time constant. #[inline(never)] fn write(self, buf: &mut [u8]) -> Option { @@ -252,7 +252,7 @@ impl WriteToBuf for &str { } impl WriteToBuf for DisplayHint { - // This need not be inlined because the return value is Result where N is 1, which is a + // This need not be inlined because the return value is Option where N is 1, which is a // compile-time constant. #[inline(never)] fn write(self, buf: &mut [u8]) -> Option { diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 9b80b6ef..63d33dad 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -6,6 +6,7 @@ use std::{ io::{BufRead as _, BufReader, ErrorKind, Write as _}, path::{Path, PathBuf}, process::{Child, Command, Output, Stdio}, + thread, }; use anyhow::{anyhow, bail, Context as _, Result}; @@ -450,17 +451,42 @@ pub fn run(opts: Options) -> Result<()> { }; } let mut qemu_child = qemu + .stdin(Stdio::piped()) .stdout(Stdio::piped()) + .stderr(Stdio::piped()) .spawn() .with_context(|| format!("failed to spawn {qemu:?}"))?; - let Child { stdout, .. } = &mut qemu_child; + let Child { + stdin, + stdout, + stderr, + .. + } = &mut qemu_child; + let mut stdin = stdin.take().unwrap(); let stdout = stdout.take().unwrap(); let stdout = BufReader::new(stdout); + let stderr = stderr.take().unwrap(); + let stderr = BufReader::new(stderr); + + let stderr = thread::Builder::new() + .spawn(move || { + for line in stderr.lines() { + let line = line.context("failed to read line from stderr")?; + eprintln!("{}", line); + // Try to get QEMU to exit on kernel panic; otherwise it might hang indefinitely. + if line.contains("end Kernel panic") { + stdin + .write_all(&[0x01, b'x']) + .context("failed to write to stdin")?; + } + } + anyhow::Ok(()) + }) + .unwrap(); let mut outcome = None; for line in stdout.lines() { - let line = - line.with_context(|| format!("failed to read line from {qemu:?}"))?; + let line = line.context("failed to read line from stdout")?; println!("{}", line); // The init program will print "init: success" or "init: failure" to indicate // the outcome of running the binaries it found in /bin. @@ -473,10 +499,6 @@ pub fn run(opts: Options) -> Result<()> { if let Some(previous) = previous { bail!("multiple exit status: previous={previous:?}, current={line}"); } - // Try to get QEMU to exit on kernel panic; otherwise it might hang indefinitely. - if line.contains("end Kernel panic") { - qemu_child.kill().context("failed to kill {qemu:?}")?; - } } } @@ -488,6 +510,8 @@ pub fn run(opts: Options) -> Result<()> { bail!("{qemu:?} failed: {output:?}") } + stderr.join().unwrap()?; + let outcome = outcome.ok_or(anyhow!("init did not exit"))?; match outcome { Ok(()) => {}