Skip to content

Initial sanitizer configurations#1

Open
RSingh1511 wants to merge 19 commits intoeclipse-score:mainfrom
RSingh1511:rs/swp-245137
Open

Initial sanitizer configurations#1
RSingh1511 wants to merge 19 commits intoeclipse-score:mainfrom
RSingh1511:rs/swp-245137

Conversation

@RSingh1511
Copy link

@RSingh1511 RSingh1511 commented Mar 3, 2026

Summary

Adds centralized sanitizer configurations (ASan, TSan, UBSan, LSan) for S-CORE C++ projects as a reusable Bazel module.

What's Included

  • Sanitizer configs with CI-optimized runtime options
  • Test workspace with positive and negative tests
  • CI workflow with GitHub Actions
  • PR/issue templates

Usage

bazel_dep(name = "score_cpp_policies", version = "0.0.0")

Signed-off-by: rahul.singh <rahul.sa.singh@partner.bmwgroup.com>
@RSingh1511 RSingh1511 marked this pull request as draft March 3, 2026 15:00
Signed-off-by: rahul.singh <rahul.sa.singh@partner.bmwgroup.com>
@RSingh1511 RSingh1511 marked this pull request as ready for review March 4, 2026 04:07
@RSingh1511 RSingh1511 requested a review from FScholPer March 4, 2026 04:08
jobs:
test-sanitizers:
name: Validate sanitizer configs
runs-on: ubuntu-latest
Copy link

Choose a reason for hiding this comment

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

why using latest? this can easily break our workflows in case it gets upgraded

Copy link
Author

Choose a reason for hiding this comment

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

Fixed to ubuntu-24.04 for stability

EXPECT_EQ(counter.load(), 4000);
}

// Test for undefined behavior detection (UBSan)
Copy link

Choose a reason for hiding this comment

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

this comment is highly misleading. the below test does not contain any UB hence, how shall it help for verifying UB detection? better adjust the comment

Copy link
Author

Choose a reason for hiding this comment

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

Done

EXPECT_EQ(vec[4], 5);
}

// Test that allocates memory (for ASan/LSan validation)
Copy link

Choose a reason for hiding this comment

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

how about

Suggested change
// Test that allocates memory (for ASan/LSan validation)
// Memory allocation test that should pass with all sanitizers

?

Copy link
Author

Choose a reason for hiding this comment

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

Done

Comment on lines +21 to +22
bazel_dep(name = "score_bazel_cpp_toolchains", version = "0.2.2")
bazel_dep(name = "score_bazel_platforms", version = "0.0.4")
Copy link

Choose a reason for hiding this comment

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

Why are these two required here? Where are they used actually?

Copy link
Author

Choose a reason for hiding this comment

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

Removed.

Copy link
Member

Choose a reason for hiding this comment

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

I have a follow-up question: why aren’t we using these platforms & toolchains here?

The reference integration relies on these toolchains configurations for release verification. If we intend for others to adopt these workflows, we should validate them against the same toolchains used in reference integration. Otherwise, we introduce an additional risk of failure due to configuration mismatches or incompatibilities.

Of course, the choice of what to test is ultimately yours. However, if the goal is for this to serve as the primary workflow for sanitizer testing across the project, then it should also pass reference integration—i.e., it must be validated with our default toolchain setups.

Copy link
Author

Choose a reason for hiding this comment

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

Done.

README.md Outdated
Comment on lines +54 to +57
- `--config=asan` - AddressSanitizer (memory errors, buffer overflows)
- `--config=tsan` - ThreadSanitizer (data races, deadlocks)
- `--config=ubsan` - UndefinedBehaviorSanitizer (undefined behavior)
- `--config=lsan` - LeakSanitizer (memory leaks)
Copy link

Choose a reason for hiding this comment

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

prefer alphabetical sorting instead?

Suggested change
- `--config=asan` - AddressSanitizer (memory errors, buffer overflows)
- `--config=tsan` - ThreadSanitizer (data races, deadlocks)
- `--config=ubsan` - UndefinedBehaviorSanitizer (undefined behavior)
- `--config=lsan` - LeakSanitizer (memory leaks)
- `--config=asan` - AddressSanitizer (memory errors, buffer overflows)
- `--config=lsan` - LeakSanitizer (memory leaks)
- `--config=tsan` - ThreadSanitizer (data races, deadlocks)
- `--config=ubsan` - UndefinedBehaviorSanitizer (undefined behavior)

Copy link
Author

Choose a reason for hiding this comment

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

Done

Copy link

Choose a reason for hiding this comment

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

how about preferring plural here? would be more appropriate in my eyes since it makes clear that it will contain multiple sanitizer configs

i.e. sanitizers/sanitizers.bazelrc

Copy link
Author

Choose a reason for hiding this comment

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

Done.

# *******************************************************************************

# ASan + UBSan + LSan (Combined - recommended for most testing)
test:asan_ubsan_lsan --compilation_mode=dbg
Copy link

Choose a reason for hiding this comment

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

please do not use dbg compliation mode. this would potentially enable code which is not part of the actual production code and hence you would potentially run into different code paths. just omit that everywhere since such compilation flags must come from the toolchain which defines the respective sanitizer features.
also see https://github.com/eclipse-score/communication/blob/main/quality/sanitizer/sanitizer.bazelrc#L20-L30 for further reference which flags we require for sanitizer configs

Copy link
Author

@RSingh1511 RSingh1511 Mar 5, 2026

Choose a reason for hiding this comment

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

Removed compilation_mode=dbg and Done as suggested.

Comment on lines +25 to +27
test:tsan --compilation_mode=dbg
test:tsan --features=tsan
test:tsan --platform_suffix=tsan
Copy link

Choose a reason for hiding this comment

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

here and also for all the other configs:

Suggested change
test:tsan --compilation_mode=dbg
test:tsan --features=tsan
test:tsan --platform_suffix=tsan
build:tsan --features=tsan
build:tsan --platform_suffix=tsan

only the runtime options should get added as test config, the others are build configs!

Copy link
Author

Choose a reason for hiding this comment

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

Done

Comment on lines +20 to +22
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
test:asan_ubsan_lsan --test_env=LSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:halt_on_error=1
Copy link

Choose a reason for hiding this comment

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

such runtime options should get extracted into a single place and then reused here instead

Suggested change
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
test:asan_ubsan_lsan --test_env=LSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:halt_on_error=1
test:_asan_runtime_options --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_runtime_options --test_env=LSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:halt_on_error=1
test:_ubsan_runtime_options --test_env=UBSAN_OPTIONS=exitcode=55:allow_addr2line=1:verbosity=1:print_stacktrace=1:halt_on_error=1
<...>
test:asan_ubsan_lsan --config=_asan_runtime_options
test:asan_ubsan_lsan --config=_lsan_runtime_options
test:asan_ubsan_lsan --config=_ubsan_runtime_options
<...>
test:asan --config=_asan_runtime_options

Copy link

Choose a reason for hiding this comment

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

and please use the following runtime options instead:

test:_asan_runtime_options --test_env=ASAN_OPTIONS="exitcode=55 allow_addr2line=1 halt_on_error=1 print_stats=1 verbosity=1 allocator_may_return_null=1 check_initialization_order=1 detect_leaks=1 detect_stack_use_after_return=1 strict_string_checks=1"
test:_lsan_runtime_options --test_env=LSAN_OPTIONS="exitcode=55 allow_addr2line=1 halt_on_error=1 print_stats=1 verbosity=1"
test:_ubsan_runtime_options --test_env=UBSAN_OPTIONS="exitcode=55 allow_addr2line=1 halt_on_error=1 print_stacktrace=1 verbosity=1"
test:_tsan_runtime_options --test_env=TSAN_OPTIONS="exitcode=55 allow_addr2line=1 halt_on_error=1 print_stats=1 verbosity=1 detect_deadlocks=1 second_deadlock_stack=1"

Copy link
Author

Choose a reason for hiding this comment

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

Done as suggested.

- name: Test with ${{ matrix.config }}
working-directory: tests
run: |
bazel test --config=${{ matrix.config }} //:sample_test --verbose_failures
Copy link

Choose a reason for hiding this comment

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

why not

Suggested change
bazel test --config=${{ matrix.config }} //:sample_test --verbose_failures
bazel test --config=${{ matrix.config }} //... --verbose_failures

?
since there will be further unit tests in this repo soon

Copy link
Author

Choose a reason for hiding this comment

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

Done as suggested.

MODULE.bazel Outdated

module(
name = "score_cpp_policies",
version = "0.0.1",
Copy link
Member

Choose a reason for hiding this comment

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

Can you please set the version to 0.0.0 here? The workflow in the S-CORE bazel registry is taking care of generating a patch when a release is picked.

Copy link
Author

Choose a reason for hiding this comment

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

Done as suggested.

LICENSE.md Outdated
@@ -0,0 +1,13 @@
Copyright 2026 Contributors to the Eclipse Foundation
Copy link
Member

Choose a reason for hiding this comment

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

Please put the entire license text here and remove .md extension. You can copy it,for example for here: https://github.com/eclipse-score/module_template/blob/main/LICENSE

General guideline: https://www.eclipse.org/projects/handbook/#legaldoc-license

Copy link
Author

Choose a reason for hiding this comment

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

Done

CONTRIBUTION.md Outdated

The [Eclipse Safe Open Vehicle Core (S-CORE)](https://projects.eclipse.org/projects/automotive.score) project develops an open-source core stack for Software Defined Vehicles (SDVs). This repository centralizes the shared C++ quality tool policies (sanitizers, clang-tidy, clang-format) that S-CORE modules reuse to maintain consistent, safety-focused defaults.

Project communication happens via the [score-dev mailing list](https://accounts.eclipse.org/mailing-list/score-dev), GitHub issues and pull requests, and the [Eclipse SCORE chatroom](https://chat.eclipse.org/#/room/#automotive.score:matrix.eclipse.org).
Copy link
Member

@4og 4og Mar 4, 2026

Choose a reason for hiding this comment

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

Where is the statement coming from? S-CORE is not using Eclipse matrix chat for communication, but Slack instead.

Copy link
Author

Choose a reason for hiding this comment

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

Removed Matrix chat reference, S-CORE uses Slack

@RSingh1511 RSingh1511 requested review from 4og and stmuench March 5, 2026 05:55
Copy link

@FScholPer FScholPer left a comment

Choose a reason for hiding this comment

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

Add the template please

@RSingh1511
Copy link
Author

Add the template please

Done>

@RSingh1511 RSingh1511 requested a review from FScholPer March 5, 2026 08:26
# *******************************************************************************

name: Tests

Copy link
Member

Choose a reason for hiding this comment

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

Please limit permissions for security

Suggested change
permissions:
contents: read

Copy link
Author

Choose a reason for hiding this comment

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

done

@@ -0,0 +1,62 @@
// *******************************************************************************
Copy link
Member

Choose a reason for hiding this comment

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

Should we also have a second test that fails in sanitizers? Otherwise, how can we know that they work?

Copy link
Author

Choose a reason for hiding this comment

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

Done

Comment on lines +39 to +40
disk-cache: ${{ github.workflow }}-${{ matrix.config }}
cache-save: ${{ github.event_name == 'push' }}
Copy link
Member

Choose a reason for hiding this comment

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

For this kind of small implementation, caching in github is superfluous IMHO. It will make the build just longer. I wouldn't introduce it yet.
But how about adding bazelisk? This one can actually help (you'll also need to add .bazelversion file(s).

Suggested change
disk-cache: ${{ github.workflow }}-${{ matrix.config }}
cache-save: ${{ github.event_name == 'push' }}
bazelisk-cache: true
cache-save: ${{ github.event_name == 'push' }}

Copy link
Author

Choose a reason for hiding this comment

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

done


steps:
- name: Checkout
uses: actions/checkout@v4
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
uses: actions/checkout@v4
uses: actions/checkout@v6

Copy link
Author

Choose a reason for hiding this comment

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

done


- name: Upload test logs on failure
if: failure()
uses: actions/upload-artifact@v4
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7

Copy link
Author

Choose a reason for hiding this comment

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

done

@RSingh1511 RSingh1511 requested a review from 4og March 5, 2026 12:28
# *******************************************************************************

# ==============================================================================
# Centralized Google Sanitizer Configurations for S-CORE C++ Modules
Copy link

Choose a reason for hiding this comment

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

let's omit the term Google here, what do you think?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

README.md Outdated
# Import centralized sanitizer configurations
try-import %workspace%/../../../external/score_cpp_policies/sanitizer/sanitizer.bazelrc
# Import centralized sanitizer configurations (fails if not found)
import %workspace%/external/score_cpp_policies~/sanitizers/sanitizers.bazelrc
Copy link

Choose a reason for hiding this comment

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

~ in between directory names intended here?

Copy link
Author

Choose a reason for hiding this comment

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

Changed to copy pattern instead of import.


### Observed behavior:

### Expected behavior
Copy link

Choose a reason for hiding this comment

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

### Expected behavior:

Copy link
Author

Choose a reason for hiding this comment

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

Done


## Checklist for the PR Reviewer

* [ ] Commits are properly organized and messages are according to the guideline
Copy link

Choose a reason for hiding this comment

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

could we link such guidelines here as a direct reference for people?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

Comment on lines +30 to +56
cc_binary(
name = "asan_fail",
srcs = ["negative/asan_fail.cpp"],
tags = ["manual"],
testonly = True,
)

cc_binary(
name = "lsan_fail",
srcs = ["negative/lsan_fail.cpp"],
tags = ["manual"],
testonly = True,
)

cc_binary(
name = "tsan_fail",
srcs = ["negative/tsan_fail.cpp"],
tags = ["manual"],
testonly = True,
)

cc_binary(
name = "ubsan_fail",
srcs = ["negative/ubsan_fail.cpp"],
tags = ["manual"],
testonly = True,
)
Copy link

Choose a reason for hiding this comment

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

you should wrap an sh script around the invocation of each test instead and then add them as sh_test here. Within the sh script, you would have to verify that the test executable fails with exitcode 55.
Do you get my my idea?
Since then, you can remove the manual tags and have these tests running in CI as well ;)

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for your suggestion. Done.

@RSingh1511 RSingh1511 requested a review from stmuench March 6, 2026 07:50
# *******************************************************************************

exports_files(
["sanitizer.bazelrc"],
Copy link

Choose a reason for hiding this comment

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

Suggested change
["sanitizer.bazelrc"],
["sanitizers.bazelrc"],

@@ -0,0 +1 @@
8.3.0
Copy link

Choose a reason for hiding this comment

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

why is this required here?

Copy link

Choose a reason for hiding this comment

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

do we really want to have the tests as separate module?

Copy link
Author

Choose a reason for hiding this comment

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

why is this required here?

Added per @4og 's feedback to enable bazelisk caching

Copy link
Author

Choose a reason for hiding this comment

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

do we really want to have the tests as separate module?

Yes, this follows the standard SCORE pattern used in score_rust_policies and other policy repos.

Comment on lines +1 to +5
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
Copy link

Choose a reason for hiding this comment

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

why is this license statement different from others?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

# ==============================================================================

cc_binary(
name = "asan_fail_bin",
Copy link

Choose a reason for hiding this comment

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

why not

Suggested change
name = "asan_fail_bin",
name = "asan_fail_test",

since _bin might be misleading

Copy link
Author

Choose a reason for hiding this comment

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

Done

@RSingh1511 RSingh1511 requested a review from stmuench March 6, 2026 08:24
README.md Outdated
```

Add to your module's `.bazelrc`:
Copy these configurations to your project's `.bazelrc`:
Copy link

Choose a reason for hiding this comment

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

NO, I have to object here. we need to find a mechsnism to make this work centrally, e.g. via run_under and using a centralized script then. otherwise the settings we define here will simply get duplicated everywhere and these will deviate over time then which is not maintainable at all!

Copy link
Member

Choose a reason for hiding this comment

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

Agree. The whole point of this repository is to avoid duplication of sanitizer config, and now the README is just asking to duplicate 🤦‍♂️

Copy link
Author

Choose a reason for hiding this comment

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

Added --run_under as suggested.

@RSingh1511 RSingh1511 force-pushed the rs/swp-245137 branch 5 times, most recently from 789a32e to 0413906 Compare March 12, 2026 08:39
@RSingh1511 RSingh1511 requested a review from 4og March 12, 2026 14:16
load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature")

# Link flags for ASan + UBSan + LSan combined
cc_args(

Choose a reason for hiding this comment

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

fsanitize options must be provided to the compile and link step! Compiler instruments code, linker adds runtime dependencies of sanitizer. One without the other does not work.

Copy link
Author

Choose a reason for hiding this comment

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

Done.

@@ -0,0 +1,3 @@
ASAN_OPTIONS=exitcode=55 allow_addr2line=1 verbosity=1 check_initialization_order=1 detect_stack_use_after_return=1 print_stats=1 halt_on_error=1 allocator_may_return_null=1 detect_leaks=1 suppressions=%ROOT%sanitizers/suppressions/asan.supp

Choose a reason for hiding this comment

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

how about adding strict_string_checks=1 to ASAN_OPTIONS here?

Copy link

@stmuench stmuench Mar 25, 2026

Choose a reason for hiding this comment

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

and maybe sort all options alphabetical to better find a certain setting?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

MODULE.bazel Outdated

module(
name = "score_cpp_policies",
version = "0.0.0",

Choose a reason for hiding this comment

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

0.0.0 really intended?

Copy link
Member

Choose a reason for hiding this comment

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

Now the registry allows empty versions.
This can be reduced to module(name = "score_cpp_policies")

Copy link
Author

Choose a reason for hiding this comment

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

Done. simplified to module(name = "score_cpp_policies")

@@ -0,0 +1,11 @@
---
Copy link
Member

Choose a reason for hiding this comment

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

There are now org-wide templates for issues: https://github.com/eclipse-score/.github/tree/main/.github/ISSUE_TEMPLATE
I suggest removing custom templates for issues from this PR.

Copy link
Author

Choose a reason for hiding this comment

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

Done.

remote = "https://github.com/bazel-contrib/toolchains_llvm",
)

bazel_dep(name = "score_cpp_policies", version = "")

Choose a reason for hiding this comment

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

empty version intended?


module(
name = "score_cpp_policies_tests",
version = "0.0.0",

Choose a reason for hiding this comment

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

value 0.0.0 intended?

build:tsan --features=tsan
build:tsan --platform_suffix=tsan
test:tsan --config=with_debug_symbols
test:tsan --cxxopt=-O1

Choose a reason for hiding this comment

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

should get removed again here since you added it in the build action features above already

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants