diff --git a/.bazelrc b/.bazelrc index aaf9466..8c0416e 100644 --- a/.bazelrc +++ b/.bazelrc @@ -82,3 +82,43 @@ coverage --combined_report=lcov coverage --test_env=COVERAGE_GCOV_OPTIONS=-bcu coverage --features=coverage coverage --cache_test_results=no + +# ============================================================================== +# Dynamic analysis (sanitizers) for Linux host builds/tests +# ============================================================================== + +# Debug symbols for sanitizer stack traces +test:with_debug_symbols --cxxopt=-g1 +test:with_debug_symbols --strip=never + +# AddressSanitizer + UndefinedBehaviorSanitizer + LeakSanitizer (Combined) +build:asan_ubsan_lsan --config=x86_64-linux +build:asan_ubsan_lsan --features=asan +build:asan_ubsan_lsan --features=ubsan +build:asan_ubsan_lsan --features=lsan +build:asan_ubsan_lsan --platform_suffix=asan_ubsan_lsan +test:asan_ubsan_lsan --config=with_debug_symbols +test:asan_ubsan_lsan --test_tag_filters=-no-asan,-no-lsan,-no-ubsan +test:asan_ubsan_lsan --@score_cpp_policies//sanitizers/flags:sanitizer=asan_ubsan_lsan +test:asan_ubsan_lsan --run_under=@score_cpp_policies//sanitizers:wrapper + +# Shortcuts for individual sanitizers +build:asan --config=asan_ubsan_lsan +test:asan --test_tag_filters=-no-asan +build:ubsan --config=asan_ubsan_lsan +test:ubsan --test_tag_filters=-no-ubsan +build:lsan --config=asan_ubsan_lsan +test:lsan --test_tag_filters=-no-lsan + +# ThreadSanitizer (cannot be combined with ASan/LSan) +build:tsan --config=x86_64-linux +build:tsan --features=tsan +build:tsan --platform_suffix=tsan +# GCC 12 promotes TSan limitation on atomic_thread_fence to -Werror=tsan. +# Downgrade to warning so external deps (score_baselibs) compile; TSan still runs. +build:tsan --cxxopt=-Wno-error=tsan +test:tsan --config=with_debug_symbols +test:tsan --cxxopt=-O1 +test:tsan --test_tag_filters=-no-tsan +test:tsan --@score_cpp_policies//sanitizers/flags:sanitizer=tsan +test:tsan --run_under=@score_cpp_policies//sanitizers:wrapper diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml new file mode 100644 index 0000000..3bca6b2 --- /dev/null +++ b/.github/workflows/sanitizers.yml @@ -0,0 +1,69 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +name: Sanitizers + +on: + pull_request: + types: [opened, reopened, synchronize] + merge_group: + types: [checks_requested] + +permissions: + contents: read + +jobs: + sanitizer-tests: + name: Bazel Tests (${{ matrix.sanitizer_config }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sanitizer_config: [asan_ubsan_lsan] + + steps: + - name: Checkout repository + uses: actions/checkout@v4.2.2 + with: + ref: ${{ github.head_ref || github.event.pull_request.head.ref || github.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + + - name: Setup Bazel with shared caching + uses: bazel-contrib/setup-bazel@0.18.0 + with: + bazelisk-version: 1.26.0 + disk-cache: true + repository-cache: true + bazelisk-cache: true + cache-save: ${{ github.event_name == 'push' }} + + - name: Run sanitizer tests via Bazel + run: | + set -euo pipefail + echo "Running: bazel test --config=${{ matrix.sanitizer_config }} //score/..." + # Note: Scoped to C/C++ targets only. Rust targets require Rust-specific + # sanitizer handling and are excluded via tag filters. + bazel test \ + --config=${{ matrix.sanitizer_config }} \ + //score/... \ + --build_tag_filters=-rust \ + --test_tag_filters=-rust \ + --verbose_failures + + - name: Upload Bazel test logs (always) + if: always() + uses: actions/upload-artifact@v6 + with: + name: bazel-testlogs-${{ matrix.sanitizer_config }} + path: bazel-testlogs/**/test.log + if-no-files-found: warn diff --git a/MODULE.bazel b/MODULE.bazel index 4897d02..88725fb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -37,6 +37,12 @@ bazel_dep(name = "score_platform", version = "0.5.3", dev_dependency = True) # Toolchains and extensions bazel_dep(name = "score_bazel_cpp_toolchains", version = "0.2.2", dev_dependency = True) bazel_dep(name = "score_toolchains_rust", version = "0.4.0", dev_dependency = True) +bazel_dep(name = "score_cpp_policies", version = "0.0.0", dev_dependency = True) +git_override( + module_name = "score_cpp_policies", + commit = "07a78d6", + remote = "https://github.com/RSingh1511/score_cpp_policies.git", +) # S-CORE crates bazel_dep(name = "score_crates", version = "0.0.6") diff --git a/quality/sanitizer/BUILD b/quality/sanitizer/BUILD new file mode 100644 index 0000000..29e8ab9 --- /dev/null +++ b/quality/sanitizer/BUILD @@ -0,0 +1,23 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +filegroup( + name = "repo_suppressions", + srcs = [ + "asan.supp", + "lsan.supp", + "tsan.supp", + "ubsan.supp", + ], + visibility = ["//visibility:public"], +) diff --git a/quality/sanitizer/asan.supp b/quality/sanitizer/asan.supp new file mode 100644 index 0000000..e9257de --- /dev/null +++ b/quality/sanitizer/asan.supp @@ -0,0 +1,17 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Suppressions for the AddressSanitizer +# See: https://clang.llvm.org/docs/AddressSanitizer.html#issue-suppression +# Every suppression requires a justification. +# Suppressions that share the same justification may be organized in a single block. diff --git a/quality/sanitizer/lsan.supp b/quality/sanitizer/lsan.supp new file mode 100644 index 0000000..4c2f2f4 --- /dev/null +++ b/quality/sanitizer/lsan.supp @@ -0,0 +1,17 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Suppressions for the LeakSanitizer +# See: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions +# Every suppression requires a justification. +# Suppressions that share the same justification may be organized in a single block. diff --git a/quality/sanitizer/tsan.supp b/quality/sanitizer/tsan.supp new file mode 100644 index 0000000..c0048b8 --- /dev/null +++ b/quality/sanitizer/tsan.supp @@ -0,0 +1,17 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Suppressions for the ThreadSanitizer +# See: https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions +# Every suppression requires a justification. +# Suppressions that share the same justification may be organized in a single block. diff --git a/quality/sanitizer/ubsan.supp b/quality/sanitizer/ubsan.supp new file mode 100644 index 0000000..3800db5 --- /dev/null +++ b/quality/sanitizer/ubsan.supp @@ -0,0 +1,17 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Suppressions for the UndefinedBehaviorSanitizer +# See: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#runtime-suppressions +# Every suppression requires a justification. +# Suppressions that share the same justification may be organized in a single block. diff --git a/score/mw/log/rust/score_log_bridge/BUILD b/score/mw/log/rust/score_log_bridge/BUILD index 45c6f1b..5258638 100644 --- a/score/mw/log/rust/score_log_bridge/BUILD +++ b/score/mw/log/rust/score_log_bridge/BUILD @@ -96,6 +96,11 @@ rust_test( edition = "2021", rustc_flags = RUSTC_FLAGS, tags = [ + "no-asan", # Rust tests with C++ FFI require sanitizer-instrumented stdlib + "no-lsan", + "no-tsan", + "no-ubsan", + "rust", "unit_tests", "ut", ], @@ -113,6 +118,7 @@ rust_binary( ], edition = "2021", rustc_flags = RUSTC_FLAGS, + tags = ["rust"], visibility = ["//visibility:public"], deps = [ ":score_log_bridge",