From a199437d53a5a5b23fd342107168b2fe6d114c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Tue, 26 Mar 2024 15:37:47 +0100 Subject: [PATCH] ci(xtask): add support for rftrace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- .github/workflows/ci.yml | 9 +++++++-- xtask/src/ci/build.rs | 9 +++++++++ xtask/src/ci/qemu.rs | 37 ++++++++++++++++++++++++++++++++++++- xtask/src/ci/rftrace.snap | 6 ++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 xtask/src/ci/rftrace.snap diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 499942f921..53171dec2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,10 +132,10 @@ jobs: include: - arch: x86_64 packages: qemu-system-x86 libcap-ng-dev libseccomp-dev - flags: --features pci-ids + flags: --features hermit/pci-ids - arch: aarch64 packages: qemu-system-aarch64 - flags: --features pci-ids + flags: --features hermit/pci-ids - arch: riscv64 packages: qemu-system-misc flags: --no-default-features @@ -157,6 +157,9 @@ jobs: run: | sudo apt-get update sudo apt-get install ${{ matrix.packages }} + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src - uses: mkroening/rust-toolchain-toml@main - uses: mkroening/rust-toolchain-toml@main with: @@ -185,6 +188,8 @@ jobs: - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --smp 4 # https://github.com/hermit-os/kernel/issues/737 if: ${{ matrix.arch != 'aarch64' }} + - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rftrace-example --virtiofsd + if: ${{ matrix.arch == 'x86_64' }} - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package httpd --features ci,dhcpv4 --netdev virtio-net-pci if: ${{ matrix.arch != 'riscv64' }} - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package httpd --features ci,dhcpv4 --netdev rtl8139 --features rtl8139 diff --git a/xtask/src/ci/build.rs b/xtask/src/ci/build.rs index 84cd3047a0..e3529ecfc1 100644 --- a/xtask/src/ci/build.rs +++ b/xtask/src/ci/build.rs @@ -26,6 +26,15 @@ impl Build { let sh = crate::sh()?; + let _push_env = if self.package.contains("rftrace") { + Some(sh.push_env( + "RUSTFLAGS", + "-Zinstrument-mcount -Cpasses=ee-instrument", + )) + } else { + None + }; + cmd!(sh, "cargo build --manifest-path ../Cargo.toml") .args(self.cargo_build.artifact.arch.ci_cargo_args()) .cargo_build_args(&self.cargo_build) diff --git a/xtask/src/ci/qemu.rs b/xtask/src/ci/qemu.rs index b7bb59480f..939b85ba7e 100644 --- a/xtask/src/ci/qemu.rs +++ b/xtask/src/ci/qemu.rs @@ -1,9 +1,10 @@ use std::io::{Read, Write}; use std::net::{TcpStream, UdpSocket}; +use std::path::Path; use std::process::{Child, Command, ExitStatus}; use std::str::from_utf8; use std::time::Duration; -use std::{env, thread}; +use std::{env, fs, thread}; use anyhow::{bail, ensure, Context, Result}; use clap::{Args, ValueEnum}; @@ -63,6 +64,10 @@ impl Qemu { let virtiofsd = self.virtiofsd.then(spawn_virtiofsd).transpose()?; thread::sleep(Duration::from_millis(100)); + if self.build.package.contains("rftrace") { + sh.create_dir("shared/tracedir")?; + } + let arch = self.build.cargo_build.artifact.arch.name(); let qemu = env::var_os("QEMU").unwrap_or_else(|| format!("qemu-system-{arch}").into()); @@ -109,6 +114,10 @@ impl Qemu { assert!(status.success()); } + if self.build.package.contains("rftrace") { + check_rftrace(&self.build.image())?; + } + Ok(()) } @@ -332,6 +341,32 @@ fn test_mioudp() -> Result<()> { Ok(()) } +fn check_rftrace(image: &Path) -> Result<()> { + let sh = crate::sh()?; + let image_name = image.file_name().unwrap().to_str().unwrap(); + + let nm = crate::binutil("nm")?; + let symbols = cmd!(sh, "{nm} --numeric-sort {image}").output()?.stdout; + sh.write_file(format!("shared/tracedir/{image_name}.sym"), symbols)?; + + let replay = cmd!( + sh, + "uftrace replay --data=shared/tracedir --output-fields=tid" + ) + .read()?; + eprintln!("[CI] replay: {replay}"); + + let expected = fs::read_to_string("xtask/src/ci/rftrace.snap")?; + if !replay.starts_with(&expected) { + eprintln!("[CI] expected: {expected}"); + bail!("rftrace output does not match snapshot"); + } + + eprintln!("[CI] replay matches snapshot"); + + Ok(()) +} + struct KillChildOnDrop(Child); impl Drop for KillChildOnDrop { diff --git a/xtask/src/ci/rftrace.snap b/xtask/src/ci/rftrace.snap new file mode 100644 index 0000000000..457fbed68b --- /dev/null +++ b/xtask/src/ci/rftrace.snap @@ -0,0 +1,6 @@ +# TID FUNCTION + [ 1] | rftrace_example::f1() { + [ 1] | rftrace_example::f2() { + [ 1] | rftrace_example::f3(); + [ 1] | } /* rftrace_example::f2 */ + [ 1] | } /* rftrace_example::f1 */