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

Run sanitizers on CI #591

Merged
merged 1 commit into from Feb 15, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/ci.yml
Expand Up @@ -108,12 +108,23 @@ jobs:
- name: clippy
run: ./ci/clippy.sh

# Run sanitizers.
san:
name: san
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust
run: rustup update nightly && rustup default nightly
- name: Run sanitizers
run: ./ci/san.sh

# Run loom tests.
loom:
name: loom
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v2
- name: Install Rust
run: rustup update stable && rustup default stable
- name: loom
Expand Down Expand Up @@ -145,6 +156,7 @@ jobs:
- dependencies
- rustfmt
- clippy
- san
- loom
- docs
runs-on: ubuntu-latest
Expand Down
40 changes: 40 additions & 0 deletions ci/san.sh
@@ -0,0 +1,40 @@
#!/bin/bash

cd "$(dirname "$0")"/..
set -ex

if [[ "$OSTYPE" != "linux"* ]]; then
exit 0
fi

rustup component add rust-src

# Run address sanitizer
# https://github.com/crossbeam-rs/crossbeam/issues/614
export ASAN_OPTIONS="detect_leaks=0"
cargo clean
# TODO: Once `cfg(sanitize = "..")` is stable, replace
# `cfg(crossbeam_sanitize)` with `cfg(sanitize = "..")` and remove
# `--cfg crossbeam_sanitize`.
RUSTFLAGS="-Dwarnings -Zsanitizer=address --cfg crossbeam_sanitize" \
cargo test --all --release --target x86_64-unknown-linux-gnu --tests --exclude benchmarks -- --test-threads=1

cargo clean
RUSTFLAGS="-Dwarnings -Zsanitizer=address --cfg crossbeam_sanitize" \
cargo run \
--release \
--target x86_64-unknown-linux-gnu \
--features nightly \
--example sanitize \
--manifest-path crossbeam-epoch/Cargo.toml

# Run memory sanitizer
cargo clean
RUSTFLAGS="-Dwarnings -Zsanitizer=memory --cfg crossbeam_sanitize" \
cargo test -Zbuild-std --all --release --target x86_64-unknown-linux-gnu --tests --exclude benchmarks -- --test-threads=1

# Run thread sanitizer
export TSAN_OPTIONS="suppressions=$(pwd)/ci/tsan"
cargo clean
RUSTFLAGS="-Dwarnings -Zsanitizer=thread --cfg crossbeam_sanitize" \
cargo test -Zbuild-std --all --release --target x86_64-unknown-linux-gnu --tests --exclude benchmarks -- --test-threads=1
20 changes: 1 addition & 19 deletions ci/test.sh
Expand Up @@ -8,7 +8,7 @@ export RUSTFLAGS="-D warnings"
if [[ -n "$TARGET" ]]; then
# If TARGET is specified, use cross for testing.
cargo install cross
cross test --all --target "$TARGET" --exclude benchmarks
cross test --all --target "$TARGET" --exclude benchmarks -- --test-threads=1

# For now, the non-host target only runs tests.
exit 0
Expand All @@ -25,22 +25,4 @@ if [[ "$RUST_VERSION" == "nightly"* ]]; then
# Benchmarks are only checked on nightly because depending on unstable features.
cargo check --all --benches
cargo check --bins --manifest-path crossbeam-channel/benchmarks/Cargo.toml

# Run address sanitizer on crossbeam-epoch
# Note: this will be significantly rewritten by https://github.com/crossbeam-rs/crossbeam/pull/591.
if [[ "$OSTYPE" == "linux"* ]]; then
cargo clean

# TODO: Once `cfg(sanitize = "..")` is stable, replace
# `cfg(crossbeam_sanitize)` with `cfg(sanitize = "..")` and remove
# `--cfg crossbeam_sanitize`.
ASAN_OPTIONS="detect_odr_violation=0 detect_leaks=0" \
RUSTFLAGS="-Z sanitizer=address --cfg crossbeam_sanitize" \
cargo run \
--release \
--target x86_64-unknown-linux-gnu \
--features nightly \
--example sanitize \
--manifest-path crossbeam-epoch/Cargo.toml
fi
fi
13 changes: 13 additions & 0 deletions ci/tsan
@@ -0,0 +1,13 @@
# TSAN suppressions file for crossbeam

# The epoch-based GC uses fences.
race:crossbeam_epoch

# Push and steal operations in crossbeam-deque may cause data races, but such
# data races are safe. If a data race happens, the value read by `steal` is
# forgotten and the steal operation is then retried.
race:crossbeam_deque*push
race:crossbeam_deque*steal

# Non-lock-free AtomicCell uses SeqLock which uses fences.
race:crossbeam_utils::atomic::atomic_cell::AtomicCell<T>::compare_exchange
2 changes: 2 additions & 0 deletions crossbeam-channel/tests/tick.rs
Expand Up @@ -127,6 +127,7 @@ fn recv() {
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
}

#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to tsan is slow
#[test]
fn recv_timeout() {
let start = Instant::now();
Expand Down Expand Up @@ -251,6 +252,7 @@ fn select() {
assert_eq!(hits.load(Ordering::SeqCst), 8);
}

#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to tsan is slow
#[test]
fn ready() {
const THREADS: usize = 4;
Expand Down
1 change: 1 addition & 0 deletions crossbeam-epoch/src/collector.rs
Expand Up @@ -199,6 +199,7 @@ mod tests {
.unwrap();
}

#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to `cfg(crossbeam_sanitize)` reduce `internal::MAX_OBJECTS`
#[test]
fn incremental() {
Comment on lines +202 to 204
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why this test fails when we reduce internal::MAX_OBJECTS, but it also fails when I run a normal test with --cfg crossbeam_sanitize. (And, except for cfg(test) code, cfg(crossbeam_sanitize) only changes internal::MAX_OBJECTS.)

$ RUSTFLAGS='--cfg crossbeam_sanitize' cargo test --lib
...

---- collector::tests::incremental stdout ----
thread 'collector::tests::incremental' panicked at 'assertion failed: curr - last <= 1024', crossbeam-epoch/src/collector.rs:227:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/80184183ba0a53aa4f491753de9502acd3d6920c/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/80184183ba0a53aa4f491753de9502acd3d6920c/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/80184183ba0a53aa4f491753de9502acd3d6920c/library/core/src/panicking.rs:50:5
   3: crossbeam_epoch::collector::tests::incremental
             at ./src/collector.rs:227:13
   4: crossbeam_epoch::collector::tests::incremental::{{closure}}
             at ./src/collector.rs:204:5
   5: core::ops::function::FnOnce::call_once
             at /Users/taiki/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
   6: core::ops::function::FnOnce::call_once
             at /rustc/80184183ba0a53aa4f491753de9502acd3d6920c/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.


failures:
    collector::tests::incremental

test result: FAILED. 35 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.01s

error: test failed, to rerun pass '--lib'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth reporting in a separate issue. @taiki-e would you please?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I've filed #662.

const COUNT: usize = 100_000;
Expand Down
1 change: 1 addition & 0 deletions crossbeam-epoch/src/internal.rs
Expand Up @@ -375,6 +375,7 @@ pub(crate) struct Local {

// Make sure `Local` is less than or equal to 2048 bytes.
// https://github.com/crossbeam-rs/crossbeam/issues/551
#[cfg(not(crossbeam_sanitize))] // `crossbeam_sanitize` reduces the size of `Local`
#[test]
fn local_size() {
assert!(
Expand Down