From e79bcb1a414490be4f585b875e3a7484eab9035a Mon Sep 17 00:00:00 2001 From: "rahul.singh" Date: Mon, 16 Feb 2026 05:03:05 +0100 Subject: [PATCH 1/5] Add sanitizer support using GCC toolchain features --- .bazelrc | 3 ++ .github/workflows/sanitizers.yml | 62 +++++++++++++++++++++++++++++ quality/sanitizer/sanitizer.bazelrc | 29 ++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 .github/workflows/sanitizers.yml create mode 100644 quality/sanitizer/sanitizer.bazelrc diff --git a/.bazelrc b/.bazelrc index aaf9466..9f50a6a 100644 --- a/.bazelrc +++ b/.bazelrc @@ -82,3 +82,6 @@ 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. +try-import %workspace%/quality/sanitizer/sanitizer.bazelrc diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml new file mode 100644 index 0000000..ed861b3 --- /dev/null +++ b/.github/workflows/sanitizers.yml @@ -0,0 +1,62 @@ +# ******************************************************************************* +# 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, tsan] + + 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/... //tests/..." + bazel test --config=${{ matrix.sanitizer_config }} //score/... //tests/... + + - 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/quality/sanitizer/sanitizer.bazelrc b/quality/sanitizer/sanitizer.bazelrc new file mode 100644 index 0000000..240e622 --- /dev/null +++ b/quality/sanitizer/sanitizer.bazelrc @@ -0,0 +1,29 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +# ASan + UBSan + LSan +test:asan_ubsan_lsan --config=x86_64-linux +test:asan_ubsan_lsan --compilation_mode=dbg +test:asan_ubsan_lsan --features=asan +test:asan_ubsan_lsan --features=ubsan +test:asan_ubsan_lsan --features=lsan +test:asan_ubsan_lsan --platform_suffix=asan_ubsan_lsan +test:asan_ubsan_lsan --test_env=ASAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:detect_leaks=1:halt_on_error=1:allocator_may_return_null=1 +test:asan_ubsan_lsan --test_env=UBSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:print_stacktrace=1:halt_on_error=1 + +# TSan +test:tsan --config=x86_64-linux +test:tsan --compilation_mode=dbg +test:tsan --features=tsan +test:tsan --platform_suffix=tsan +test:tsan --test_env=TSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:halt_on_error=1:detect_deadlocks=1 From d2c40e79da196741add7b728814a2c1ff13343f9 Mon Sep 17 00:00:00 2001 From: "rahul.singh" Date: Mon, 16 Feb 2026 15:15:39 +0100 Subject: [PATCH 2/5] Remove TSan from CI due to kernel compatibility issues --- .github/workflows/sanitizers.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index ed861b3..47f17e5 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -29,7 +29,7 @@ jobs: strategy: fail-fast: false matrix: - sanitizer_config: [asan_ubsan_lsan, tsan] + sanitizer_config: [asan_ubsan_lsan] steps: - name: Checkout repository @@ -50,8 +50,9 @@ jobs: - name: Run sanitizer tests via Bazel run: | set -euo pipefail - echo "Running: bazel test --config=${{ matrix.sanitizer_config }} //score/... //tests/..." - bazel test --config=${{ matrix.sanitizer_config }} //score/... //tests/... + echo "Running: bazel test --config=${{ matrix.sanitizer_config }} //tests/cpp/..." + # Note: Only testing C++ targets as Rust sanitizers require different configuration + bazel test --config=${{ matrix.sanitizer_config }} //tests/cpp/... - name: Upload Bazel test logs (always) if: always() From 1ede9eb10f063b25e07c0a9060e6fd4a552fe5ea Mon Sep 17 00:00:00 2001 From: "rahul.singh" Date: Wed, 25 Feb 2026 11:33:10 +0100 Subject: [PATCH 3/5] Fix sanitizer workflow to test //score/... targets --- .github/workflows/sanitizers.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index 47f17e5..1083f39 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -50,9 +50,8 @@ jobs: - name: Run sanitizer tests via Bazel run: | set -euo pipefail - echo "Running: bazel test --config=${{ matrix.sanitizer_config }} //tests/cpp/..." - # Note: Only testing C++ targets as Rust sanitizers require different configuration - bazel test --config=${{ matrix.sanitizer_config }} //tests/cpp/... + echo "Running: bazel test --config=${{ matrix.sanitizer_config }} //score/..." + bazel test --config=${{ matrix.sanitizer_config }} //score/... - name: Upload Bazel test logs (always) if: always() From 5bc82b84996fbee7cd14b3c63647a46a4b2baf0b Mon Sep 17 00:00:00 2001 From: "rahul.singh" Date: Wed, 25 Feb 2026 12:34:42 +0100 Subject: [PATCH 4/5] Adopt centralized sanitizer infrastructure from score_cpp_policies --- .bazelrc | 40 ++++++++++++++++++++++-- .github/workflows/sanitizers.yml | 9 +++++- MODULE.bazel | 6 ++++ quality/sanitizer/sanitizer.bazelrc | 29 ----------------- score/mw/log/rust/score_log_bridge/BUILD | 6 ++++ 5 files changed, 58 insertions(+), 32 deletions(-) delete mode 100644 quality/sanitizer/sanitizer.bazelrc diff --git a/.bazelrc b/.bazelrc index 9f50a6a..d6a9cad 100644 --- a/.bazelrc +++ b/.bazelrc @@ -83,5 +83,41 @@ coverage --test_env=COVERAGE_GCOV_OPTIONS=-bcu coverage --features=coverage coverage --cache_test_results=no -# Dynamic analysis (sanitizers) for Linux host builds/tests. -try-import %workspace%/quality/sanitizer/sanitizer.bazelrc +# ============================================================================== +# 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 --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 index 1083f39..3bca6b2 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -51,7 +51,14 @@ jobs: run: | set -euo pipefail echo "Running: bazel test --config=${{ matrix.sanitizer_config }} //score/..." - 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() diff --git a/MODULE.bazel b/MODULE.bazel index 4897d02..3cf58c3 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 = "7d2f594", + 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/sanitizer.bazelrc b/quality/sanitizer/sanitizer.bazelrc deleted file mode 100644 index 240e622..0000000 --- a/quality/sanitizer/sanitizer.bazelrc +++ /dev/null @@ -1,29 +0,0 @@ -# ******************************************************************************* -# 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 -# ******************************************************************************* - -# ASan + UBSan + LSan -test:asan_ubsan_lsan --config=x86_64-linux -test:asan_ubsan_lsan --compilation_mode=dbg -test:asan_ubsan_lsan --features=asan -test:asan_ubsan_lsan --features=ubsan -test:asan_ubsan_lsan --features=lsan -test:asan_ubsan_lsan --platform_suffix=asan_ubsan_lsan -test:asan_ubsan_lsan --test_env=ASAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:detect_leaks=1:halt_on_error=1:allocator_may_return_null=1 -test:asan_ubsan_lsan --test_env=UBSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:print_stacktrace=1:halt_on_error=1 - -# TSan -test:tsan --config=x86_64-linux -test:tsan --compilation_mode=dbg -test:tsan --features=tsan -test:tsan --platform_suffix=tsan -test:tsan --test_env=TSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:halt_on_error=1:detect_deadlocks=1 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", From f70f1c0c77680fd1e8c1b77f709ba671f9658f57 Mon Sep 17 00:00:00 2001 From: "rahul.singh" Date: Mon, 16 Mar 2026 13:24:22 +0100 Subject: [PATCH 5/5] Add repo-specific suppression files --- .bazelrc | 1 + MODULE.bazel | 2 +- quality/sanitizer/BUILD | 23 +++++++++++++++++++++++ quality/sanitizer/asan.supp | 17 +++++++++++++++++ quality/sanitizer/lsan.supp | 17 +++++++++++++++++ quality/sanitizer/tsan.supp | 17 +++++++++++++++++ quality/sanitizer/ubsan.supp | 17 +++++++++++++++++ 7 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 quality/sanitizer/BUILD create mode 100644 quality/sanitizer/asan.supp create mode 100644 quality/sanitizer/lsan.supp create mode 100644 quality/sanitizer/tsan.supp create mode 100644 quality/sanitizer/ubsan.supp diff --git a/.bazelrc b/.bazelrc index d6a9cad..8c0416e 100644 --- a/.bazelrc +++ b/.bazelrc @@ -118,6 +118,7 @@ build:tsan --platform_suffix=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/MODULE.bazel b/MODULE.bazel index 3cf58c3..88725fb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,7 +40,7 @@ bazel_dep(name = "score_toolchains_rust", version = "0.4.0", dev_dependency = Tr bazel_dep(name = "score_cpp_policies", version = "0.0.0", dev_dependency = True) git_override( module_name = "score_cpp_policies", - commit = "7d2f594", + commit = "07a78d6", remote = "https://github.com/RSingh1511/score_cpp_policies.git", ) 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.