Skip to content

Commit

Permalink
Merge pull request #1114 from hermit-os/test-rftrace
Browse files Browse the repository at this point in the history
ci(xtask): add support for rftrace
  • Loading branch information
mkroening authored Mar 27, 2024
2 parents 4e9c13c + 8ac5fa5 commit fc99a6b
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 31 deletions.
11 changes: 8 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ jobs:
profile: [dev, release]
include:
- arch: x86_64
packages: qemu-system-x86 libcap-ng-dev libseccomp-dev
flags: --features pci-ids
packages: qemu-system-x86 libcap-ng-dev libseccomp-dev uftrace
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
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down
29 changes: 4 additions & 25 deletions xtask/src/archive.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::collections::HashSet;
use std::env;
use std::fmt::Write;
use std::path::{Path, PathBuf};

use anyhow::{anyhow, Result};
use anyhow::Result;
use goblin::archive::Archive as GoblinArchive;
use goblin::elf64::header;
use llvm_tools::LlvmTools;
use xshell::cmd;

pub struct Archive(PathBuf);
Expand Down Expand Up @@ -51,7 +49,7 @@ impl Archive {
};

let all_symbols = {
let nm = binutil("nm")?;
let nm = crate::binutil("nm")?;
let stdout = cmd!(sh, "{nm} --export-symbols {archive}").output()?.stdout;
String::from_utf8(stdout)?
};
Expand All @@ -75,7 +73,7 @@ impl Archive {
let rename_path = archive.with_extension("redefine-syms");
sh.write_file(&rename_path, symbol_renames)?;

let objcopy = binutil("objcopy")?;
let objcopy = crate::binutil("objcopy")?;
cmd!(sh, "{objcopy} --redefine-syms={rename_path} {archive}").run()?;

sh.remove_path(&rename_path)?;
Expand All @@ -88,7 +86,7 @@ impl Archive {
let archive = self.as_ref();
let file = file.as_ref();

let ar = binutil("ar")?;
let ar = crate::binutil("ar")?;
cmd!(sh, "{ar} qL {archive} {file}").run()?;

Ok(())
Expand All @@ -115,22 +113,3 @@ impl Archive {
Ok(())
}
}

fn binutil(name: &str) -> Result<PathBuf> {
let exe_suffix = env::consts::EXE_SUFFIX;
let exe = format!("llvm-{name}{exe_suffix}");

let path = LlvmTools::new()
.map_err(|err| match err {
llvm_tools::Error::NotFound => anyhow!(
"Could not find llvm-tools component\n\
\n\
Maybe the rustup component `llvm-tools` is missing? Install it through: `rustup component add llvm-tools`"
),
err => anyhow!("{err:?}"),
})?
.tool(&exe)
.ok_or_else(|| anyhow!("could not find {exe}"))?;

Ok(path)
}
22 changes: 22 additions & 0 deletions xtask/src/binutil.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use std::path::PathBuf;

use anyhow::{anyhow, Result};

pub fn binutil(name: &str) -> Result<PathBuf> {
let exe_suffix = std::env::consts::EXE_SUFFIX;
let exe = format!("llvm-{name}{exe_suffix}");

let path = llvm_tools::LlvmTools::new()
.map_err(|err| match err {
llvm_tools::Error::NotFound => anyhow!(
"Could not find llvm-tools component\n\
\n\
Maybe the rustup component `llvm-tools` is missing? Install it through: `rustup component add llvm-tools`"
),
err => anyhow!("{err:?}"),
})?
.tool(&exe)
.ok_or_else(|| anyhow!("could not find {exe}"))?;

Ok(path)
}
9 changes: 9 additions & 0 deletions xtask/src/ci/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<post-inline>",
))
} 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)
Expand Down
41 changes: 38 additions & 3 deletions xtask/src/ci/qemu.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -109,6 +114,10 @@ impl Qemu {
assert!(status.success());
}

if self.build.package.contains("rftrace") {
check_rftrace(&self.build.image())?;
}

Ok(())
}

Expand Down Expand Up @@ -246,9 +255,9 @@ impl Qemu {
fn spawn_virtiofsd() -> Result<KillChildOnDrop> {
let sh = crate::sh()?;

sh.create_dir("foo")?;
sh.create_dir("shared")?;

let cmd = cmd!(sh, "virtiofsd --socket-path=./vhostqemu --shared-dir ./foo --announce-submounts --sandbox none --seccomp none --inode-file-handles=never");
let cmd = cmd!(sh, "virtiofsd --socket-path=./vhostqemu --shared-dir ./shared --announce-submounts --sandbox none --seccomp none --inode-file-handles=never");

eprintln!("$ {cmd}");

Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions xtask/src/ci/rftrace.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# TID FUNCTION
[ 1] | rftrace_example::f1() {
[ 1] | rftrace_example::f2() {
[ 1] | rftrace_example::f3()
2 changes: 2 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
mod arch;
mod archive;
mod artifact;
mod binutil;
mod build;
mod cargo_build;
mod ci;
Expand All @@ -11,6 +12,7 @@ mod clippy;
use std::path::Path;

use anyhow::Result;
pub(crate) use binutil::binutil;
use clap::Parser;
use xshell::Shell;

Expand Down

0 comments on commit fc99a6b

Please sign in to comment.