Skip to content

Commit 93f443c

Browse files
authored
Add support for sanitizer (#15)
The following commit enables 4 new features: asan, tsan, lsan and ubsan.
1 parent 65f80ea commit 93f443c

5 files changed

Lines changed: 239 additions & 5 deletions

File tree

examples/BUILD

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
"""Small C++ CLI application for sanity testing"""
1515

16-
load("@rules_cc//cc:defs.bzl", "cc_binary")
16+
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
1717

1818
cc_binary(
1919
name = "main_cpp",
@@ -35,4 +35,14 @@ cc_test(
3535
name = "math_lib_test",
3636
srcs = ["math_lib_test.cpp"],
3737
deps = [":math_lib"],
38+
)
39+
40+
cc_test(
41+
name = "asan_test",
42+
srcs = ["asan_test.cpp"],
43+
features = ["asan"],
44+
deps = [
45+
"@googletest//:gtest",
46+
"@googletest//:gtest_main",
47+
]
3848
)

examples/MODULE.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ bazel_dep(name = "score_bazel_platforms", version = "0.0.4")
3636
# C++ Rules for Bazel
3737
# *******************************************************************************
3838
bazel_dep(name = "rules_cc", version = "0.2.14")
39+
bazel_dep(name = "googletest", version = "1.17.0")
3940

4041
# *******************************************************************************
4142
# Set dependency to Bazel C/C++ Toolchain repository - with overriding path

examples/asan_test.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/********************************************************************************
2+
* Copyright (c) 2025 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Apache License Version 2.0 which is available at
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* SPDX-License-Identifier: Apache-2.0
12+
********************************************************************************/
13+
14+
#include <gtest/gtest.h>
15+
16+
// Reproduce the buggy logic as a callable function (rather than a real main()).
17+
static int buggy(int argc) {
18+
int *array = new int[100];
19+
delete[] array;
20+
21+
// Prevent compiler from optimizing away the UB access.
22+
volatile int idx = argc;
23+
24+
// Use-after-free (+ potential OOB if argc >= 100).
25+
return array[idx];
26+
}
27+
28+
TEST(BugReproTest, UseAfterFree_ShouldCrashUnderSanitizers) {
29+
// Under ASan/UBSan this should reliably abort.
30+
// Regex ".*" accepts any sanitizer death message.
31+
ASSERT_DEATH({ (void)buggy(0); }, ".*");
32+
}
33+
34+
TEST(BugReproTest, OutOfBoundsPlusUaf_ShouldCrashUnderSanitizers) {
35+
// argc=200 also implies out-of-bounds in addition to use-after-free.
36+
ASSERT_DEATH({ (void)buggy(200); }, ".*");
37+
}

packages/version_matrix.bzl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
VERSION_MATRIX = {
1818
"aarch64-linux-gcc-12.2.0": {
19-
"url": "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.3/aarch64-unknown-linux-gnu_gcc12.tar.gz",
19+
"url": "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.4/aarch64-unknown-linux-gnu_gcc12.tar.gz",
2020
"build_file": "@score_bazel_cpp_toolchains//packages/linux/aarch64/gcc/12.2.0:gcc.BUILD",
2121
"strip_prefix": "aarch64-unknown-linux-gnu",
22-
"sha256": "57153340625581b199408391b895c84651382d3edd4c60fadbf0399f9dad21e1",
22+
"sha256": "7279b1adb50361b21f5266b001980b6febb35fa8d83170901196b9edae3f06d9",
2323
},
2424
"aarch64-qnx-sdp-8.0.0": {
2525
"url": "https://www.qnx.com/download/download/79858/installation.tgz",
@@ -28,10 +28,10 @@ VERSION_MATRIX = {
2828
"sha256": "f2e0cb21c6baddbcb65f6a70610ce498e7685de8ea2e0f1648f01b327f6bac63",
2929
},
3030
"x86_64-linux-gcc-12.2.0": {
31-
"url": "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/0.0.1/x86_64-unknown-linux-gnu_gcc12.tar.gz",
31+
"url": "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.4/x86_64-unknown-linux-gnu_gcc12.tar.gz",
3232
"build_file": "@score_bazel_cpp_toolchains//packages/linux/x86_64/gcc/12.2.0:gcc.BUILD",
3333
"strip_prefix": "x86_64-unknown-linux-gnu",
34-
"sha256": "457f5f20f57528033cb840d708b507050d711ae93e009388847e113b11bf3600",
34+
"sha256": "e9b9a7a63a5f8271b76d6e2057906b95c7a244e4931a8e10edeaa241e9f7c11e",
3535
},
3636
"x86_64-qnx-sdp-8.0.0": {
3737
"url": "https://www.qnx.com/download/download/79858/installation.tgz",

templates/linux/cc_toolchain_config.bzl.template

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,187 @@ def _impl(ctx):
237237
],
238238
)
239239

240+
sanitizer_feature = feature(
241+
name = "sanitizer",
242+
flag_sets = [
243+
flag_set(
244+
actions = all_compile_actions,
245+
flag_groups = [
246+
flag_group(
247+
flags = [
248+
"-fno-omit-frame-pointer",
249+
"-fno-sanitize-recover=all", # TODO: Check if this is needed.
250+
"-g",
251+
],
252+
),
253+
],
254+
with_features = [
255+
with_feature_set(
256+
features = [
257+
"asan",
258+
"lsan",
259+
"tsan",
260+
"ubsan",
261+
],
262+
not_features = ["opt"],
263+
)
264+
],
265+
),
266+
],
267+
)
268+
269+
asan_feature = feature(
270+
name = "asan",
271+
implies = ["sanitizer"],
272+
flag_sets = [
273+
flag_set(
274+
actions = all_compile_actions,
275+
flag_groups = [
276+
flag_group(
277+
flags = [
278+
"-fsanitize=address",
279+
"-DADDRESS_SANITIZER",
280+
"-O0",
281+
],
282+
),
283+
],
284+
with_features = [
285+
with_feature_set(
286+
not_features = ["opt"],
287+
)
288+
],
289+
),
290+
flag_set(
291+
actions = all_link_actions,
292+
flag_groups = [
293+
flag_group(
294+
flags = [
295+
"-fsanitize=address",
296+
],
297+
),
298+
],
299+
with_features = [
300+
with_feature_set(
301+
not_features = ["opt"],
302+
)
303+
],
304+
),
305+
],
306+
)
307+
308+
lsan_feature = feature(
309+
name = "lsan",
310+
implies = ["sanitizer"],
311+
flag_sets = [
312+
flag_set(
313+
actions = all_compile_actions,
314+
flag_groups = [
315+
flag_group(
316+
flags = [
317+
"-fsanitize=leak",
318+
"-O0",
319+
],
320+
),
321+
],
322+
with_features = [
323+
with_feature_set(
324+
not_features = ["opt"],
325+
)
326+
],
327+
),
328+
flag_set(
329+
actions = all_link_actions,
330+
flag_groups = [
331+
flag_group(
332+
flags = [
333+
"-fsanitize=leak",
334+
],
335+
),
336+
],
337+
with_features = [
338+
with_feature_set(
339+
not_features = ["opt"],
340+
)
341+
],
342+
),
343+
],
344+
)
345+
346+
tsan_feature = feature(
347+
name = "tsan",
348+
implies = ["sanitizer"],
349+
flag_sets = [
350+
flag_set(
351+
actions = all_compile_actions,
352+
flag_groups = [
353+
flag_group(
354+
flags = [
355+
"-fsanitize=thread",
356+
"-O1",
357+
],
358+
),
359+
],
360+
with_features = [
361+
with_feature_set(
362+
not_features = ["opt"],
363+
)
364+
],
365+
),
366+
flag_set(
367+
actions = all_link_actions,
368+
flag_groups = [
369+
flag_group(
370+
flags = [
371+
"-fsanitize=thread",
372+
],
373+
),
374+
],
375+
with_features = [
376+
with_feature_set(
377+
not_features = ["opt"],
378+
)
379+
],
380+
),
381+
],
382+
)
383+
384+
ubsan_feature = feature(
385+
name = "ubsan",
386+
implies = ["sanitizer"],
387+
flag_sets = [
388+
flag_set(
389+
actions = all_compile_actions,
390+
flag_groups = [
391+
flag_group(
392+
flags = [
393+
"-fsanitize=undefined",
394+
],
395+
),
396+
],
397+
with_features = [
398+
with_feature_set(
399+
not_features = ["opt"],
400+
)
401+
],
402+
),
403+
flag_set(
404+
actions = all_link_actions,
405+
flag_groups = [
406+
flag_group(
407+
flags = [
408+
"-fsanitize=undefined",
409+
],
410+
),
411+
],
412+
with_features = [
413+
with_feature_set(
414+
not_features = ["opt"],
415+
)
416+
],
417+
),
418+
],
419+
)
420+
240421
minimal_warnings_feature = feature(
241422
name = "minimal_warnings",
242423
enabled = False,
@@ -378,6 +559,11 @@ def _impl(ctx):
378559
# after a command line parameter from a feature at the beginning of the list.
379560

380561
features = [
562+
sanitizer_feature,
563+
asan_feature,
564+
lsan_feature,
565+
tsan_feature,
566+
ubsan_feature,
381567
dbg_feature,
382568
unfiltered_compile_flags_feature,
383569
default_compile_flags_feature,

0 commit comments

Comments
 (0)