Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ jobs:
strategy:
fail-fast: false
matrix:
config:
- asan_ubsan_lsan
- tsan
include:
- config: asan_ubsan_lsan
description: "ASan + UBSan + LSan"
- config: asan
description: "AddressSanitizer"
- config: ubsan
description: "UndefinedBehaviorSanitizer"
- config: lsan
description: "LeakSanitizer"
- config: tsan
description: "ThreadSanitizer"

steps:
- name: Checkout
Expand Down
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ Planned: clang-tidy, clang-format, code coverage policies.

| Config | Sanitizers | Notes |
|--------|-----------|-------|
| `--config=asan_ubsan_lsan` | ASan + UBSan + LSan | **Recommended** — catches memory errors, UB, and leaks |
| `--config=asan` | AddressSanitizer | Alias for `asan_ubsan_lsan` |
| `--config=ubsan` | UndefinedBehaviorSanitizer | Alias for `asan_ubsan_lsan` |
| `--config=lsan` | LeakSanitizer | Alias for `asan_ubsan_lsan` |
| `--config=tsan` | ThreadSanitizer | Cannot be combined with ASan |
| `--config=asan` | AddressSanitizer | Memory errors, buffer overflows |
| `--config=ubsan` | UndefinedBehaviorSanitizer | Integer overflow, null deref |
| `--config=lsan` | LeakSanitizer | Memory leaks |
| `--config=tsan` | ThreadSanitizer | Data races, deadlocks — cannot combine with ASan/LSan |
| `--config=asan_ubsan_lsan` | ASan + UBSan + LSan | **Recommended default for CI** |
| `--config=tsan_ubsan` | TSan + UBSan | Threading + undefined behavior |

## Usage

Expand Down Expand Up @@ -105,6 +106,18 @@ bazel test --config=asan_ubsan_lsan //...
bazel test --config=tsan //...
```

## Migration from v0.x

The `--@score_cpp_policies//sanitizers/flags:sanitizer=<value>` string flag has been removed.
Replace any direct flag usage with the equivalent `--config=` alias:

| Old | New |
|-----|-----|
| `--@score_cpp_policies//sanitizers/flags:sanitizer=asan_ubsan_lsan` | `--config=asan_ubsan_lsan` |
| `--@score_cpp_policies//sanitizers/flags:sanitizer=tsan` | `--config=tsan` |

`--config=asan`, `--config=ubsan`, and `--config=lsan` now activate exactly their named sanitizer rather than the combined `asan_ubsan_lsan` mode.

## Contributing

See [CONTRIBUTION.md](CONTRIBUTION.md) for guidelines. All commits must follow [Eclipse Foundation commit rules](https://www.eclipse.org/projects/handbook/#resources-commit). Contributors must sign the ECA and DCO.
Expand Down
73 changes: 40 additions & 33 deletions sanitizers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,59 @@ exports_files(
visibility = ["//visibility:public"],
)

filegroup(
name = "env_template",
srcs = select({
"//sanitizers/flags:tsan": ["templates/tsan.env.template"],
"//sanitizers/flags:asan_ubsan_lsan": ["templates/asan_ubsan_lsan.env.template"],
}),
target_compatible_with = ["//sanitizers/constraints:any_sanitizer"],
)
_SANITIZERS = {
"asan": "templates/asan.env.template",
"ubsan": "templates/ubsan.env.template",
"lsan": "templates/lsan.env.template",
"tsan": "templates/tsan.env.template",
}

_ROOTS = {
"absolute": "/",
"relative": "./",
}

[
expand_template(
name = name + "_env",
out = name + "_sanitizer.env",
substitutions = {"%ROOT%": root},
name = sanitizer + "_" + root_name + "_env",
out = sanitizer + "_" + root_name + "_sanitizer.env",
substitutions = {"%ROOT%": root_path},
target_compatible_with = ["//sanitizers/constraints:any_sanitizer"],
template = ":env_template",
template = template,
visibility = ["//visibility:public"],
)
for name, root in [
("absolute", "/"),
("relative", "./"),
]
for sanitizer, template in _SANITIZERS.items()
for root_name, root_path in _ROOTS.items()
]

filegroup(
name = "suppressions",
srcs = select({
"//sanitizers/flags:tsan": ["suppressions/tsan.supp"],
"//sanitizers/flags:asan_ubsan_lsan": [
sh_binary(
name = "wrapper",
srcs = ["wrapper.sh"],
data = select({
"//sanitizers/flags:asan_on": [
"suppressions/asan.supp",
"suppressions/lsan.supp",
":asan_relative_env",
],
"//conditions:default": [],
}) + select({
"//sanitizers/flags:ubsan_on": [
"suppressions/ubsan.supp",
":ubsan_relative_env",
],
"//conditions:default": [],
}) + select({
"//sanitizers/flags:lsan_on": [
"suppressions/lsan.supp",
":lsan_relative_env",
],
"//conditions:default": [],
}) + select({
"//sanitizers/flags:tsan_on": [
"suppressions/tsan.supp",
":tsan_relative_env",
],
"//conditions:default": [],
}),
target_compatible_with = ["//sanitizers/constraints:any_sanitizer"],
visibility = ["//visibility:public"],
)

sh_binary(
name = "wrapper",
srcs = ["wrapper.sh"],
data = [
":relative_env",
":suppressions",
],
target_compatible_with = ["//sanitizers/constraints:any_sanitizer"],
visibility = ["//visibility:public"],
)
70 changes: 67 additions & 3 deletions sanitizers/constraints/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,27 @@ alias(
)

alias(
name = "no_asan_ubsan_lsan",
name = "no_asan",
actual = select({
"//sanitizers/flags:asan_on": "@platforms//:incompatible",
"//conditions:default": ":always_true",
}),
visibility = ["//visibility:public"],
)

alias(
name = "no_ubsan",
actual = select({
"//sanitizers/flags:ubsan_on": "@platforms//:incompatible",
"//conditions:default": ":always_true",
}),
visibility = ["//visibility:public"],
)

alias(
name = "no_lsan",
actual = select({
"//sanitizers/flags:asan_ubsan_lsan": "@platforms//:incompatible",
"//sanitizers/flags:lsan_on": "@platforms//:incompatible",
"//conditions:default": ":always_true",
}),
visibility = ["//visibility:public"],
Expand All @@ -42,8 +60,54 @@ alias(
alias(
name = "no_tsan",
actual = select({
"//sanitizers/flags:tsan": "@platforms//:incompatible",
"//sanitizers/flags:tsan_on": "@platforms//:incompatible",
"//conditions:default": ":always_true",
}),
visibility = ["//visibility:public"],
)

alias(
name = "no_asan_ubsan_lsan",
actual = select({
"//sanitizers/flags:any_asan_ubsan_lsan": "@platforms//:incompatible",
"//conditions:default": ":always_true",
}),
visibility = ["//visibility:public"],
)

# "Only when" constraints — for negative tests that must run only under their specific sanitizer.
alias(
name = "only_asan",
actual = select({
"//sanitizers/flags:asan_on": ":always_true",
"//conditions:default": "@platforms//:incompatible",
}),
visibility = ["//visibility:public"],
)

alias(
name = "only_ubsan",
actual = select({
"//sanitizers/flags:ubsan_on": ":always_true",
"//conditions:default": "@platforms//:incompatible",
}),
visibility = ["//visibility:public"],
)

alias(
name = "only_lsan",
actual = select({
"//sanitizers/flags:lsan_on": ":always_true",
"//conditions:default": "@platforms//:incompatible",
}),
visibility = ["//visibility:public"],
)

alias(
name = "only_tsan",
actual = select({
"//sanitizers/flags:tsan_on": ":always_true",
"//conditions:default": "@platforms//:incompatible",
}),
visibility = ["//visibility:public"],
)
Loading
Loading