Skip to content

Commit b71b944

Browse files
bors[bot]taiki-e
andauthored
Merge #591
591: Run sanitizers on CI r=jeehoonkang a=taiki-e This adds AddressSanitizer/MemorySanitizer/ThreadSanitizer tests to CI. See #589 (tsan: data race in deque), #644 (tsan: data race in atomic), and #614 (asan: memory leak in skiplist) for issues reported by sanitizers. Closes #154 Closes #589 Closes #644 Refs: - https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/sanitizer.html - https://github.com/google/sanitizers/wiki Co-authored-by: Taiki Endo <[email protected]>
2 parents e85d8f4 + b05c62d commit b71b944

File tree

7 files changed

+71
-20
lines changed

7 files changed

+71
-20
lines changed

.github/workflows/ci.yml

+13-1
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,23 @@ jobs:
108108
- name: clippy
109109
run: ./ci/clippy.sh
110110

111+
# Run sanitizers.
112+
san:
113+
name: san
114+
runs-on: ubuntu-latest
115+
steps:
116+
- uses: actions/checkout@v2
117+
- name: Install Rust
118+
run: rustup update nightly && rustup default nightly
119+
- name: Run sanitizers
120+
run: ./ci/san.sh
121+
111122
# Run loom tests.
112123
loom:
113124
name: loom
114125
runs-on: ubuntu-latest
115126
steps:
116-
- uses: actions/checkout@master
127+
- uses: actions/checkout@v2
117128
- name: Install Rust
118129
run: rustup update stable && rustup default stable
119130
- name: loom
@@ -145,6 +156,7 @@ jobs:
145156
- dependencies
146157
- rustfmt
147158
- clippy
159+
- san
148160
- loom
149161
- docs
150162
runs-on: ubuntu-latest

ci/san.sh

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
cd "$(dirname "$0")"/..
4+
set -ex
5+
6+
if [[ "$OSTYPE" != "linux"* ]]; then
7+
exit 0
8+
fi
9+
10+
rustup component add rust-src
11+
12+
# Run address sanitizer
13+
# https://github.com/crossbeam-rs/crossbeam/issues/614
14+
export ASAN_OPTIONS="detect_leaks=0"
15+
cargo clean
16+
# TODO: Once `cfg(sanitize = "..")` is stable, replace
17+
# `cfg(crossbeam_sanitize)` with `cfg(sanitize = "..")` and remove
18+
# `--cfg crossbeam_sanitize`.
19+
RUSTFLAGS="-Dwarnings -Zsanitizer=address --cfg crossbeam_sanitize" \
20+
cargo test --all --release --target x86_64-unknown-linux-gnu --tests --exclude benchmarks -- --test-threads=1
21+
22+
cargo clean
23+
RUSTFLAGS="-Dwarnings -Zsanitizer=address --cfg crossbeam_sanitize" \
24+
cargo run \
25+
--release \
26+
--target x86_64-unknown-linux-gnu \
27+
--features nightly \
28+
--example sanitize \
29+
--manifest-path crossbeam-epoch/Cargo.toml
30+
31+
# Run memory sanitizer
32+
cargo clean
33+
RUSTFLAGS="-Dwarnings -Zsanitizer=memory --cfg crossbeam_sanitize" \
34+
cargo test -Zbuild-std --all --release --target x86_64-unknown-linux-gnu --tests --exclude benchmarks -- --test-threads=1
35+
36+
# Run thread sanitizer
37+
export TSAN_OPTIONS="suppressions=$(pwd)/ci/tsan"
38+
cargo clean
39+
RUSTFLAGS="-Dwarnings -Zsanitizer=thread --cfg crossbeam_sanitize" \
40+
cargo test -Zbuild-std --all --release --target x86_64-unknown-linux-gnu --tests --exclude benchmarks -- --test-threads=1

ci/test.sh

+1-19
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export RUSTFLAGS="-D warnings"
88
if [[ -n "$TARGET" ]]; then
99
# If TARGET is specified, use cross for testing.
1010
cargo install cross
11-
cross test --all --target "$TARGET" --exclude benchmarks
11+
cross test --all --target "$TARGET" --exclude benchmarks -- --test-threads=1
1212

1313
# For now, the non-host target only runs tests.
1414
exit 0
@@ -25,22 +25,4 @@ if [[ "$RUST_VERSION" == "nightly"* ]]; then
2525
# Benchmarks are only checked on nightly because depending on unstable features.
2626
cargo check --all --benches
2727
cargo check --bins --manifest-path crossbeam-channel/benchmarks/Cargo.toml
28-
29-
# Run address sanitizer on crossbeam-epoch
30-
# Note: this will be significantly rewritten by https://github.com/crossbeam-rs/crossbeam/pull/591.
31-
if [[ "$OSTYPE" == "linux"* ]]; then
32-
cargo clean
33-
34-
# TODO: Once `cfg(sanitize = "..")` is stable, replace
35-
# `cfg(crossbeam_sanitize)` with `cfg(sanitize = "..")` and remove
36-
# `--cfg crossbeam_sanitize`.
37-
ASAN_OPTIONS="detect_odr_violation=0 detect_leaks=0" \
38-
RUSTFLAGS="-Z sanitizer=address --cfg crossbeam_sanitize" \
39-
cargo run \
40-
--release \
41-
--target x86_64-unknown-linux-gnu \
42-
--features nightly \
43-
--example sanitize \
44-
--manifest-path crossbeam-epoch/Cargo.toml
45-
fi
4628
fi

ci/tsan

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# TSAN suppressions file for crossbeam
2+
3+
# The epoch-based GC uses fences.
4+
race:crossbeam_epoch
5+
6+
# Push and steal operations in crossbeam-deque may cause data races, but such
7+
# data races are safe. If a data race happens, the value read by `steal` is
8+
# forgotten and the steal operation is then retried.
9+
race:crossbeam_deque*push
10+
race:crossbeam_deque*steal
11+
12+
# Non-lock-free AtomicCell uses SeqLock which uses fences.
13+
race:crossbeam_utils::atomic::atomic_cell::AtomicCell<T>::compare_exchange

crossbeam-channel/tests/tick.rs

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ fn recv() {
127127
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
128128
}
129129

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

255+
#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to tsan is slow
254256
#[test]
255257
fn ready() {
256258
const THREADS: usize = 4;

crossbeam-epoch/src/collector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ mod tests {
199199
.unwrap();
200200
}
201201

202+
#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to `cfg(crossbeam_sanitize)` reduce `internal::MAX_OBJECTS`
202203
#[test]
203204
fn incremental() {
204205
const COUNT: usize = 100_000;

crossbeam-epoch/src/internal.rs

+1
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ pub(crate) struct Local {
375375

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

0 commit comments

Comments
 (0)