Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci(xtask): add support for rftrace #1114

Merged
merged 3 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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