Skip to content

Commit

Permalink
Run Sanitizers and Valgrind on tests as part of CI
Browse files Browse the repository at this point in the history
Unfortunately we can't yet run MemorySanitizer on `cargo test` as there
is a known memory bug in rustc's test runner. [1]

[1]: rust-lang/rust#39610
  • Loading branch information
jacob-hughes committed Nov 4, 2019
1 parent 1293771 commit 41cd328
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .buildbot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ export PATH=`pwd`/.cargo/bin/:$PATH
rustup component add --toolchain nightly rustfmt-preview || cargo +nightly install --force rustfmt-nightly

cargo +nightly fmt --all -- --check

cargo test

# Run gc tests with sanitizers
SANITIZERS="thread" cargo test --test gc_tests --target x86_64-unknown-linux-gnu
VALGRIND="true" cargo test --test gc_tests --target x86_64-unknown-linux-gnu
34 changes: 33 additions & 1 deletion gc_tests/run_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ use tempdir::TempDir;
static CRATE_NAME: &'static str = "gcmalloc";

fn main() {
let sanitizers: Vec<String> = match env::var("SANITIZERS") {
Ok(ref s) => s.split(';').map(|s| s.to_string()).collect(),
Err(_) => Vec::new(),
};

let valgrind: bool = match env::var("VALGRIND") {
Ok(ref s) => s == "true",
Err(_) => false,
};

// We grab the rlibs from `target/<debug | release>/` but in order
// for them to exist here, they must have been moved from `deps/`.
// Simply running `cargo test` will not do this, instead, we must
Expand Down Expand Up @@ -65,6 +75,10 @@ fn main() {
let lib_arg = [CRATE_NAME, "=", lib_path.to_str().unwrap()].concat();
let deps_arg = ["dependency=", deps_path.to_str().unwrap()].concat();

let san_flags = sanitizers.iter().map(|x| format!("-Zsanitizer={}", x));

compiler.args(san_flags);

compiler.args(&[
"--edition=2018",
"-o",
Expand All @@ -78,7 +92,25 @@ fn main() {
lib_arg.as_str(),
]);

let runtime = Command::new(exe);
assert!(
!(valgrind && !sanitizers.is_empty()),
"Valgrind can't be used on code compiled with sanitizers"
);

let mut runtime;
if valgrind {
let suppr_file = PathBuf::from("gc_tests/valgrind.supp");
let suppressions = ["--suppressions=", suppr_file.to_str().unwrap()].concat();
runtime = Command::new("valgrind");
runtime.args(&[
"--error-exitcode=1",
suppressions.as_str(),
exe.to_str().unwrap(),
]);
} else {
runtime = Command::new(exe);
};

vec![("Compiler", compiler), ("Run-time", runtime)]
})
.run();
Expand Down
5 changes: 4 additions & 1 deletion gc_tests/tests/alloc_info_oom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Run-time:
// status: error
// stderr: Allocation failed: Metadata list full
// stderr:
// ...
// Allocation failed: Metadata list full
// ...

extern crate gcmalloc;

Expand Down
7 changes: 7 additions & 0 deletions gc_tests/valgrind.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
<uninitialized_stack>
Memcheck:Cond
...
fun:scan_stack
}

1 change: 1 addition & 0 deletions src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ impl AllocMetadata {
}

/// Removes the metadata associated with an allocation.
#[cfg(test)]
pub(crate) fn remove(ptr: usize) {
ALLOC_LOCK.lock();

Expand Down

0 comments on commit 41cd328

Please sign in to comment.