Add anyhow for better errors
This commit is contained in:
parent
9a08103872
commit
d7cf79a092
70
Cargo.lock
generated
70
Cargo.lock
generated
@ -2,6 +2,21 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
@ -61,12 +76,36 @@ dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.11"
|
||||
@ -421,6 +460,12 @@ dependencies = [
|
||||
"wasi 0.14.5+wasi-0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
@ -573,6 +618,15 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.4"
|
||||
@ -618,6 +672,15 @@ dependencies = [
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@ -692,6 +755,7 @@ dependencies = [
|
||||
name = "qemu-nyx-runner"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"csv",
|
||||
"libnyx",
|
||||
@ -809,6 +873,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
|
@ -12,6 +12,7 @@ libnyx = { git = "https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork" }
|
||||
pt-dump-decoder = { path = "pt-dump-decoder" }
|
||||
csv = "1.3.1"
|
||||
clap.workspace = true
|
||||
anyhow = { version = "1.0.99", features = ["backtrace"] }
|
||||
|
||||
[workspace.dependencies]
|
||||
clap = { version = "4.5.47", features = ["derive"] }
|
@ -1,13 +1,12 @@
|
||||
use crate::benchmark::Benchmark;
|
||||
use crate::nyx::{NyxRunner, TraceMode};
|
||||
use std::error::Error;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct BenchmarkNyxNoPt(NyxRunner);
|
||||
|
||||
impl BenchmarkNyxNoPt {
|
||||
pub fn new(client_path: &Path) -> Result<Self, Box<dyn Error>> {
|
||||
pub fn new(client_path: &Path) -> anyhow::Result<Self> {
|
||||
Ok(BenchmarkNyxNoPt(NyxRunner::setup(
|
||||
client_path,
|
||||
TraceMode::Disabled,
|
||||
|
@ -2,14 +2,13 @@ use crate::benchmark::{Benchmark, ToCsv};
|
||||
use crate::nyx::{NyxRunner, TraceMode};
|
||||
use csv::Writer;
|
||||
use pt_dump_decoder::{AnalyzeData, analyze_dump};
|
||||
use std::error::Error;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct BenchmarkNyx(NyxRunner);
|
||||
|
||||
impl BenchmarkNyx {
|
||||
pub fn new(client_bin: &Path) -> Result<Self, Box<dyn Error>> {
|
||||
pub fn new(client_bin: &Path) -> anyhow::Result<Self> {
|
||||
Ok(BenchmarkNyx(NyxRunner::setup(
|
||||
client_bin,
|
||||
TraceMode::Enabled,
|
||||
|
@ -11,7 +11,6 @@ use crate::benchmark_baseline::Baseline;
|
||||
use crate::benchmark_nyx_no_pt::BenchmarkNyxNoPt;
|
||||
use crate::benchmark_nyx_pt::BenchmarkNyx;
|
||||
use clap::Parser;
|
||||
use std::error::Error;
|
||||
use std::fmt::Debug;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -30,7 +29,7 @@ struct Args {
|
||||
debug: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
if args.debug {
|
||||
@ -56,7 +55,7 @@ fn benchmark<B: Benchmark>(
|
||||
binary_name: &str,
|
||||
output_dir: &Path,
|
||||
mut benchmark: B,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
) -> anyhow::Result<()> {
|
||||
warmup(&mut benchmark);
|
||||
let results = benchmark_loop(&mut benchmark);
|
||||
write_results::<B>(binary_name, output_dir, &results)?;
|
||||
@ -89,10 +88,10 @@ fn write_results<B: Benchmark>(
|
||||
binary_name: &str,
|
||||
output_dir: &Path,
|
||||
results: &[B::BenchmarkResult],
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
) -> anyhow::Result<()> {
|
||||
fs::create_dir_all(output_dir)?;
|
||||
let filename = format!("benchmark_{binary_name}_{}", B::TITLE);
|
||||
let file = std::fs::File::create(output_dir.join(filename))?;
|
||||
let file = fs::File::create(output_dir.join(filename))?;
|
||||
let mut writer = csv::WriterBuilder::new().from_writer(file);
|
||||
writer.write_record(B::BenchmarkResult::HEADERS)?;
|
||||
for result in results {
|
||||
|
38
src/nyx.rs
38
src/nyx.rs
@ -1,8 +1,8 @@
|
||||
//! This module contains functionality to download and setup nyx,
|
||||
//! so that it can be used to execute a binary.
|
||||
|
||||
use anyhow::{Context, anyhow, bail};
|
||||
use libnyx::{NyxConfig, NyxProcess, NyxProcessRole, NyxReturnValue};
|
||||
use std::error::Error;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::time::Duration;
|
||||
@ -19,7 +19,7 @@ pub enum TraceMode {
|
||||
pub struct NyxRunner(NyxProcess);
|
||||
|
||||
impl NyxRunner {
|
||||
pub fn setup(client_bin: &Path, trace_mode: TraceMode) -> Result<Self, Box<dyn Error>> {
|
||||
pub fn setup(client_bin: &Path, trace_mode: TraceMode) -> anyhow::Result<Self> {
|
||||
if let Err(e) = fs::remove_dir_all(WORKDIR_PATH)
|
||||
&& !matches!(e.kind(), io::ErrorKind::NotFound)
|
||||
{
|
||||
@ -28,7 +28,9 @@ impl NyxRunner {
|
||||
let sharedir = setup_nyx(&PathBuf::from("nyx_data"), client_bin)?;
|
||||
let sharedir = sharedir.to_str().expect("Expected unicode path");
|
||||
|
||||
let mut nyx_config = NyxConfig::load(sharedir)?;
|
||||
let mut nyx_config = NyxConfig::load(sharedir)
|
||||
.map_err(|err| anyhow!(err))
|
||||
.with_context(|| "Creating nyx config")?;
|
||||
nyx_config.set_workdir_path(WORKDIR_PATH.to_string());
|
||||
nyx_config.set_input_buffer_size(0x2000);
|
||||
nyx_config.set_nyx_debug_log_path("qemu_nyx.log".to_string());
|
||||
@ -37,7 +39,9 @@ impl NyxRunner {
|
||||
nyx_config.set_process_role(NyxProcessRole::StandAlone);
|
||||
nyx_config.print();
|
||||
|
||||
let mut nyx_runner = NyxProcess::new(&mut nyx_config, 0)?;
|
||||
let mut nyx_runner = NyxProcess::new(&mut nyx_config, 0)
|
||||
.map_err(|err| anyhow!(err))
|
||||
.with_context(|| "Creating Nyx Process")?;
|
||||
|
||||
nyx_runner.option_set_trace_mode(true);
|
||||
nyx_runner.option_set_reload_mode(false);
|
||||
@ -79,30 +83,31 @@ impl Drop for NyxRunner {
|
||||
/// [client] Is the path to the client binary.
|
||||
///
|
||||
/// Returns the path to the working directory
|
||||
pub fn setup_nyx(out_dir: &Path, client: &Path) -> Result<PathBuf, io::Error> {
|
||||
fn inner(out_dir: &Path, client: &Path) -> Result<PathBuf, io::Error> {
|
||||
pub fn setup_nyx(out_dir: &Path, client: &Path) -> anyhow::Result<PathBuf> {
|
||||
fn inner(out_dir: &Path, client: &Path) -> anyhow::Result<PathBuf> {
|
||||
if !out_dir.exists() {
|
||||
fs::create_dir(out_dir)?;
|
||||
}
|
||||
|
||||
println!("Installing nyx...");
|
||||
setup_nyx_tools(out_dir)?;
|
||||
setup_nyx_tools(out_dir).with_context(|| "Setting up nyx tools")?;
|
||||
|
||||
create_nyx_workdir(out_dir, client)
|
||||
create_nyx_workdir(out_dir, client).with_context(|| "Creating the nyx working directory")
|
||||
}
|
||||
|
||||
// Clean up the out directory if something went wrong
|
||||
match inner(out_dir, client) {
|
||||
Ok(path) => Ok(path),
|
||||
Err(err) => {
|
||||
fs::remove_dir_all(out_dir)?;
|
||||
fs::remove_dir_all(out_dir)
|
||||
.with_context(|| format!("Error while handling error: {err}"))?;
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn shell(cwd: impl AsRef<Path>, command_string: &str) -> Result<(), io::Error> {
|
||||
fn shell(cwd: impl AsRef<Path>, command_string: &str) -> anyhow::Result<()> {
|
||||
println!("Running ({}) {command_string}", cwd.as_ref().display());
|
||||
|
||||
let cwd = cwd.as_ref();
|
||||
@ -118,9 +123,7 @@ fn shell(cwd: impl AsRef<Path>, command_string: &str) -> Result<(), io::Error> {
|
||||
let mut process = command.spawn()?;
|
||||
let exit_status = process.wait()?;
|
||||
if !exit_status.success() {
|
||||
return Err(io::Error::other(format!(
|
||||
"Command ({command_string}) failed with {exit_status}"
|
||||
)));
|
||||
bail!("Command ({command_string}) failed with {exit_status}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -128,7 +131,7 @@ fn shell(cwd: impl AsRef<Path>, command_string: &str) -> Result<(), io::Error> {
|
||||
|
||||
/// Downloads and compiles qemu-nyx and packer and compiles them for the current architecture
|
||||
/// This means that cross-compilation is not supported
|
||||
fn setup_nyx_tools(out_dir: &Path) -> Result<(), io::Error> {
|
||||
fn setup_nyx_tools(out_dir: &Path) -> anyhow::Result<()> {
|
||||
let packer_path = out_dir.join("packer");
|
||||
let qemu_path = out_dir.join("QEMU-Nyx");
|
||||
if !packer_path.exists() {
|
||||
@ -142,7 +145,7 @@ fn setup_nyx_tools(out_dir: &Path) -> Result<(), io::Error> {
|
||||
)?;
|
||||
|
||||
// Compile with maximum optimizations
|
||||
let qemu_compile_mode = "lto";
|
||||
let qemu_compile_mode = "debug_static";
|
||||
shell(
|
||||
qemu_path,
|
||||
&format!("bash compile_qemu_nyx.sh {qemu_compile_mode}"),
|
||||
@ -152,8 +155,9 @@ fn setup_nyx_tools(out_dir: &Path) -> Result<(), io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_nyx_workdir(out_dir: &Path, client_bin: &Path) -> Result<PathBuf, io::Error> {
|
||||
let client_bin = fs::canonicalize(client_bin)?;
|
||||
fn create_nyx_workdir(out_dir: &Path, client_bin: &Path) -> anyhow::Result<PathBuf> {
|
||||
let client_bin =
|
||||
fs::canonicalize(client_bin).with_context(|| format!("canonicalizing {client_bin:?}"))?;
|
||||
let client_bin = client_bin.to_str().expect("Expected unicode path");
|
||||
// Create the directory and move required binaries to it
|
||||
shell(
|
||||
|
Loading…
x
Reference in New Issue
Block a user