add context to all fs calls (#423)

Adds additional context in error handling to all `std::fs` and `tokio::fs` calls.

Fixes #309
This commit is contained in:
bmc-msft
2021-01-11 15:55:22 -05:00
committed by GitHub
parent d573100a97
commit 465727680d
14 changed files with 166 additions and 52 deletions

View File

@ -36,7 +36,7 @@ use crate::tasks::{
coverage::{recorder::CoverageRecorder, total::TotalCoverage},
utils::default_bool_true,
};
use anyhow::Result;
use anyhow::{Context, Result};
use async_trait::async_trait;
use futures::stream::StreamExt;
use onefuzz::{
@ -124,7 +124,9 @@ impl CoverageTask {
seen_inputs = true;
}
fs::remove_dir_all(&dir.path).await?;
fs::remove_dir_all(&dir.path).await.with_context(|| {
format!("unable to remove readonly_inputs: {}", dir.path.display())
})?;
}
if seen_inputs {
@ -154,7 +156,12 @@ impl CoverageTask {
processor: &mut CoverageProcessor,
corpus_dir: &SyncedDir,
) -> Result<bool> {
let mut corpus = fs::read_dir(&corpus_dir.path).await?;
let mut corpus = fs::read_dir(&corpus_dir.path).await.with_context(|| {
format!(
"unable to read corpus coverage directory: {}",
corpus_dir.path.display()
)
})?;
let mut seen_inputs = false;
while let Some(input) = corpus.next().await {
@ -208,7 +215,12 @@ impl CoverageProcessor {
if !self.module_totals.contains_key(&module) {
let parent = &self.config.coverage.path.join("by-module");
fs::create_dir_all(parent).await?;
fs::create_dir_all(parent).await.with_context(|| {
format!(
"unable to create by-module coverage directory: {}",
parent.display()
)
})?;
let module_total = parent.join(&module);
let total = TotalCoverage::new(module_total);
self.module_totals.insert(module.clone(), total);
@ -226,7 +238,9 @@ impl CoverageProcessor {
for file in &files {
verbose!("checking {:?}", file);
let mut content = fs::read(file).await?;
let mut content = fs::read(file)
.await
.with_context(|| format!("unable to read module coverage: {}", file.display()))?;
self.update_module_total(file, &content).await?;
sum.append(&mut content);
}
@ -234,7 +248,9 @@ impl CoverageProcessor {
let mut combined = path.as_os_str().to_owned();
combined.push(".cov");
fs::write(&combined, sum).await?;
fs::write(&combined, sum)
.await
.with_context(|| format!("unable to write combined coverage file: {:?}", combined))?;
Ok(combined.into())
}

View File

@ -8,7 +8,7 @@ use std::{
sync::Arc,
};
use anyhow::Result;
use anyhow::{Context, Result};
use onefuzz::{
fs::{has_files, OwnedDir},
sha256::digest_file,
@ -47,7 +47,12 @@ impl CoverageRecorder {
self.config.coverage.path.join("inputs").join(digest)
};
fs::create_dir_all(&coverage_path).await?;
fs::create_dir_all(&coverage_path).await.with_context(|| {
format!(
"unable to create coverage path: {}",
coverage_path.display()
)
})?;
let script = self.invoke_debugger_script(test_input, &coverage_path)?;
let output = script.wait_with_output().await?;
@ -77,7 +82,14 @@ impl CoverageRecorder {
}
if !has_files(&coverage_path).await? {
tokio::fs::remove_dir(&coverage_path).await?;
tokio::fs::remove_dir(&coverage_path)
.await
.with_context(|| {
format!(
"unable to remove coverage path: {}",
coverage_path.display()
)
})?;
bail!("no coverage files for input: {}", test_input.display());
}

View File

@ -2,7 +2,7 @@
// Licensed under the MIT License.
use crate::tasks::{config::CommonConfig, heartbeat::HeartbeatSender, utils::default_bool_true};
use anyhow::Result;
use anyhow::{Context, Result};
use futures::{future::try_join_all, stream::StreamExt};
use onefuzz::{
fs::list_files,
@ -120,7 +120,15 @@ impl LibFuzzerFuzzTask {
let mut entries = tokio::fs::read_dir(local_input_dir.path()).await?;
while let Some(Ok(entry)) = entries.next().await {
let destination_path = self.config.inputs.path.clone().join(entry.file_name());
tokio::fs::rename(entry.path(), destination_path).await?;
tokio::fs::rename(&entry.path(), &destination_path)
.await
.with_context(|| {
format!(
"unable to move crashing input into results directory: {} - {}?",
entry.path().display(),
destination_path.display()
)
})?;
}
}
}

View File

@ -1,13 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use anyhow::{Error, Result};
use anyhow::{Context, Error, Result};
use onefuzz::telemetry::EventData;
use std::path::Path;
use tokio::io::AsyncBufReadExt;
pub async fn read_stats(output_path: impl AsRef<Path>) -> Result<Vec<EventData>, Error> {
let f = tokio::fs::File::open(output_path).await?;
let output_path = output_path.as_ref();
let f = tokio::fs::File::open(&output_path).await.with_context(|| {
format!(
"unable to open AFL stats for read: {}",
output_path.display()
)
})?;
let mut stats = Vec::new();
let reader = tokio::io::BufReader::new(f);