Skip to content
Open
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: 14 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,17 @@ test:asan_ubsan_lsan --build_tests_only
build:asan --config=asan_ubsan_lsan
build:ubsan --config=asan_ubsan_lsan
build:lsan --config=asan_ubsan_lsan

# ThreadSanitizer (cannot be combined with ASan/LSan)
build:tsan --config=with_debug_symbols
build:tsan --copt=-fsanitize=thread
build:tsan --copt=-O1
build:tsan --linkopt=-fsanitize=thread
# GCC TSan doesn't instrument atomic_thread_fence; suppress the resulting -Wtsan
# warning so it doesn't become a build error in external deps that use -Werror.
build:tsan --cxxopt=-Wno-tsan
build:tsan --platform_suffix=tsan
build:tsan --@score_cpp_policies//sanitizers/flags:sanitizer=tsan
test:tsan --run_under=//tools/sanitizers:tsan_setarch_wrapper
test:tsan --test_tag_filters=-no-tsan
test:tsan --build_tests_only
2 changes: 1 addition & 1 deletion .github/workflows/sanitizers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
strategy:
fail-fast: false
matrix:
config: [asan_ubsan_lsan]
config: [asan_ubsan_lsan, tsan]
steps:
- name: Checkout code
uses: actions/checkout@v4.2.2
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ ASan + UBSan + LSan (recommended):
bazel test --config=asan_ubsan_lsan --config=x86_64-linux //score/... //tests/...
```

TSan:

```sh
bazel test --config=tsan --config=x86_64-linux //score/... //tests/...
```

To build all components with ``score::mw::log`` enabled, use this command:

```sh
Expand Down
1 change: 1 addition & 0 deletions score/health_monitor/src/cpp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ cc_gtest_unit_test(
}),
tags = [
"no-asan",
"no-tsan",
],
deps = [
"//score/health_monitor/src/cpp:health_monitoring_cc_stub_supervisor",
Expand Down
2 changes: 2 additions & 0 deletions score/health_monitor/src/rust/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ rust_test(
}),
tags = [
"no-asan",
"no-tsan",
],
deps = ["@score_baselibs_rust//src/log/stdout_logger"],
)
Expand All @@ -96,6 +97,7 @@ rust_test(
tags = [
"loom",
"no-asan",
"no-tsan",
],
target_compatible_with = ["@platforms//os:linux"],
deps = [
Expand Down
1 change: 1 addition & 0 deletions score/launch_manager/daemon/src/process_state_client/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ cc_library(
cc_test(
name = "process_state_client_ut",
srcs = ["process_state_client_ut.cpp"],
tags = ["no-tsan"],
deps = [
":process_state_client",
"//score/launch_manager/daemon/src/process_state_client/details:process_state_receiver",
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/bazel/integration.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def integration_test(name, srcs, test_binaries, args = [], deps = [], data = [],
})

# The test container does not ship the sanitizer runtime; daemon fails to start.
sanitizer_tags = ["no-asan"]
sanitizer_tags = ["no-asan", "no-tsan"]
tags = kwargs.pop("tags", []) + sanitizer_tags

py_itf_test(
Expand Down
32 changes: 32 additions & 0 deletions tools/sanitizers/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# *******************************************************************************
# 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
# *******************************************************************************

load(":wrapper.bzl", "expand_executable_template")

expand_executable_template(
name = "tsan_setarch_wrapper_sh",
out = "tsan_setarch_wrapper.sh",
template = "tsan_setarch_wrapper.sh.tpl",
wrapper = "@score_cpp_policies//sanitizers:wrapper",
)

sh_binary(
name = "tsan_setarch_wrapper",
srcs = [":tsan_setarch_wrapper_sh"],
data = [
"@bazel_tools//tools/bash/runfiles",
"@score_cpp_policies//sanitizers:wrapper",
],
target_compatible_with = ["@platforms//os:linux"],
visibility = ["//visibility:public"],

@NicolasFussberger NicolasFussberger Jun 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I really appreciate your effort to narrow the scope of ASLR disabling just for the test run.
Does this binary need to be public or can this stay repo-private?

)
26 changes: 26 additions & 0 deletions tools/sanitizers/tsan_setarch_wrapper.sh.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# *******************************************************************************
# 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
# *******************************************************************************

# --- begin runfiles.bash initialization v3 ---
set -uo pipefail
f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo >&2 "ERROR: cannot find $f"; exit 1; }; f=
# --- end runfiles.bash initialization v3 ---

exec setarch "$(uname -m)" -R -- "$(rlocation %WRAPPER_RLOCATION%)" "$@"
41 changes: 41 additions & 0 deletions tools/sanitizers/wrapper.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# *******************************************************************************
# 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
# *******************************************************************************

"""Generates an executable script from a template, with the runfiles path of
another executable target baked in as a substitution."""

def _expand_executable_template_impl(ctx):
out = ctx.actions.declare_file(ctx.attr.out)
wrapper_label = ctx.attr.wrapper.label
ctx.actions.expand_template(
template = ctx.file.template,
output = out,
substitutions = {
"%WRAPPER_RLOCATION%": "{}/{}/{}".format(
wrapper_label.workspace_name,
wrapper_label.package,
wrapper_label.name,
),
},
is_executable = True,
)
return [DefaultInfo(files = depset([out]))]

expand_executable_template = rule(
implementation = _expand_executable_template_impl,
attrs = {
"out": attr.string(mandatory = True),
"template": attr.label(allow_single_file = True, mandatory = True),
"wrapper": attr.label(mandatory = True),
},
)
Loading