Add sanitizers to CI builds

- Added Address and Thread sanitizers for Debian Bookworm builds
- Updated build-deps action to support sanitizer flags
- Modified strategy matrix generation to include sanitizer configurations
- Updated Conan profiles for sanitizer support
- Added InsertNewlineAtEOF setting to clang-format
This commit is contained in:
Pratik Mankawde
2025-11-10 15:54:44 +00:00
parent 30f7ef7676
commit 0b1bd42cc0
5 changed files with 80 additions and 53 deletions

View File

@@ -69,7 +69,6 @@ IndentFunctionDeclarationAfterType: false
IndentRequiresClause: true IndentRequiresClause: true
IndentWidth: 4 IndentWidth: 4
IndentWrappedFunctionNames: false IndentWrappedFunctionNames: false
InsertNewlineAtEOF: true
NamespaceIndentation: None NamespaceIndentation: None
ObjCSpaceAfterProperty: false ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false ObjCSpaceBeforeProtocolList: false

View File

@@ -23,8 +23,7 @@ inputs:
default: "verbose" default: "verbose"
sanitizers: sanitizers:
description: "The sanitizers to enable ('Address+UndefinedBehaviour' or 'Thread+UndefinedBehaviour')." description: "The sanitizers to enable ('Address+UndefinedBehaviour' or 'Thread+UndefinedBehaviour')."
required: false required: true
type: string
default: "" default: ""
runs: runs:

View File

@@ -34,6 +34,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# The default CMake target is 'all' for Linux and MacOS and 'install' # The default CMake target is 'all' for Linux and MacOS and 'install'
# for Windows, but it can get overridden for certain configurations. # for Windows, but it can get overridden for certain configurations.
cmake_target = 'install' if os["distro_name"] == 'windows' else 'all' cmake_target = 'install' if os["distro_name"] == 'windows' else 'all'
cxx_flags = ''
# We build and test all configurations by default, except for Windows in # We build and test all configurations by default, except for Windows in
# Debug, because it is too slow, as well as when code coverage is # Debug, because it is too slow, as well as when code coverage is
@@ -57,18 +58,18 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if os['distro_name'] == 'debian': if os['distro_name'] == 'debian':
skip = True skip = True
if os['distro_version'] == 'bookworm': if os['distro_version'] == 'bookworm':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}' cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}'
skip = False skip = False
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False skip = False
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-16' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-16' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64':
cmake_args = f'-Dvoidstar=ON {cmake_args}' cmake_args = f'-Dvoidstar=ON {cmake_args}'
skip = False skip = False
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-17' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-17' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}' cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}'
skip = False skip = False
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-20' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False skip = False
if skip: if skip:
continue continue
@@ -79,10 +80,10 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if os['distro_name'] == 'rhel': if os['distro_name'] == 'rhel':
skip = True skip = True
if os['distro_version'] == '9': if os['distro_version'] == '9':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False skip = False
elif os['distro_version'] == '10': elif os['distro_version'] == '10':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False skip = False
if skip: if skip:
continue continue
@@ -95,14 +96,14 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if os['distro_name'] == 'ubuntu': if os['distro_name'] == 'ubuntu':
skip = True skip = True
if os['distro_version'] == 'jammy': if os['distro_version'] == 'jammy':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64':
skip = False skip = False
elif os['distro_version'] == 'noble': elif os['distro_version'] == 'noble':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-14' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'gcc-14' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False skip = False
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-18' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-18' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False skip = False
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-19' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-19' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64':
skip = False skip = False
if skip: if skip:
continue continue
@@ -117,10 +118,16 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if os['distro_name'] == 'windows' and not (build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'windows/amd64'): if os['distro_name'] == 'windows' and not (build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'windows/amd64'):
continue continue
# Add sanitizer flags
sanitizers_flags = 'undefined,float-divide-by-zero'
if os['compiler_name'] == 'gcc':
sanitizers_flags = f'{sanitizers_flags},signed-integer-overflow'
elif os['compiler_name'] == 'clang':
sanitizers_flags = f'{sanitizers_flags},signed-integer-overflow,unsigned-integer-overflow'
# Additional CMake arguments. # Additional CMake arguments.
cmake_args = f'{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON' cmake_args = f'{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON'
if not f'{os['compiler_name']}-{os['compiler_version']}' in ['gcc-12', 'clang-16']: if not f'{os["compiler_name"]}-{os["compiler_version"]}' in ['gcc-12', 'clang-16']:
cmake_args = f'{cmake_args} -Dwextra=ON' cmake_args = f'{cmake_args} -Dwextra=ON'
if build_type == 'Release': if build_type == 'Release':
cmake_args = f'{cmake_args} -Dassert=ON' cmake_args = f'{cmake_args} -Dassert=ON'
@@ -131,15 +138,16 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue continue
# We skip all clang-20 on arm64 due to boost 1.86 build error # We skip all clang-20 on arm64 due to boost 1.86 build error
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and architecture['platform'] == 'linux/arm64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'clang-20' and architecture['platform'] == 'linux/arm64':
continue continue
# Enable code coverage for Debian Bookworm using GCC 15 in Debug and no # Enable code coverage for Debian Bookworm using GCC 15 in Debug and no
# Unity on linux/amd64 # Unity on linux/amd64
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': if f'{os["compiler_name"]}-{os["compiler_version"]}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
cmake_args = f'-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}' cmake_args = f'-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 {cmake_args}'
cmake_target = 'coverage' cmake_target = 'coverage'
build_only = True build_only = True
cxx_flags = f'-O0 {cxx_flags}'
# Generate a unique name for the configuration, e.g. macos-arm64-debug # Generate a unique name for the configuration, e.g. macos-arm64-debug
# or debian-bookworm-gcc-12-amd64-release-unity. # or debian-bookworm-gcc-12-amd64-release-unity.
@@ -150,7 +158,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
config_name += f'-{n}' config_name += f'-{n}'
if (n := os['compiler_version']) != '': if (n := os['compiler_version']) != '':
config_name += f'-{n}' config_name += f'-{n}'
config_name += f'-{architecture['platform'][architecture['platform'].find('/')+1:]}' config_name += f'-{architecture["platform"][architecture["platform"].find("/")+1:]}'
config_name += f'-{build_type.lower()}' config_name += f'-{build_type.lower()}'
if '-Dunity=ON' in cmake_args: if '-Dunity=ON' in cmake_args:
config_name += '-unity' config_name += '-unity'
@@ -159,9 +167,18 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# so that they are easier to identify in the GitHub Actions UI, as long # so that they are easier to identify in the GitHub Actions UI, as long
# names get truncated. Add Address and Thread (both coupled with UB) sanitizers when the distro is bookworm. # names get truncated. Add Address and Thread (both coupled with UB) sanitizers when the distro is bookworm.
if os['distro_version'] == 'bookworm': if os['distro_version'] == 'bookworm':
if "-O0" in cxx_flags:
cxx_flags.replace("-O0", "-O1")
else:
cxx_flags += " -O1"
if cxx_flags:
cmake_args_flags = f'{cmake_args} -DCMAKE_CXX_FLAGS="-fsanitize=address,{sanitizers_flags} -fno-omit-frame-pointer {cxx_flags}"'
else:
cmake_args_flags = f'{cmake_args}'
configurations.append({ configurations.append({
'config_name': config_name, 'config_name': config_name + "_ASAN",
'cmake_args': cmake_args, 'cmake_args': cmake_args_flags,
'cmake_target': cmake_target, 'cmake_target': cmake_target,
'build_only': build_only, 'build_only': build_only,
'build_type': build_type, 'build_type': build_type,
@@ -169,9 +186,13 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
'architecture': architecture, 'architecture': architecture,
'sanitizers': "Address" 'sanitizers': "Address"
}) })
if cxx_flags:
cmake_args_flags = f'{cmake_args} -DCMAKE_CXX_FLAGS="-fsanitize=thread,{sanitizers_flags} -fno-omit-frame-pointer {cxx_flags}"'
else:
cmake_args_flags = f'{cmake_args}'
configurations.append({ configurations.append({
'config_name': config_name, 'config_name': config_name+ "_TSAN",
'cmake_args': cmake_args, 'cmake_args': cmake_args_flags,
'cmake_target': cmake_target, 'cmake_target': cmake_target,
'build_only': build_only, 'build_only': build_only,
'build_type': build_type, 'build_type': build_type,
@@ -180,9 +201,13 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
'sanitizers': "Thread" 'sanitizers': "Thread"
}) })
else: else:
if cxx_flags:
cmake_args_flags = f'{cmake_args} -DCMAKE_CXX_FLAGS={cxx_flags}'
else:
cmake_args_flags = f'{cmake_args}'
configurations.append({ configurations.append({
'config_name': config_name, 'config_name': config_name,
'cmake_args': cmake_args, 'cmake_args': cmake_args_flags,
'cmake_target': cmake_target, 'cmake_target': cmake_target,
'build_only': build_only, 'build_only': build_only,
'build_type': build_type, 'build_type': build_type,

View File

@@ -15,168 +15,168 @@
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "12", "compiler_version": "12",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "13", "compiler_version": "13",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14", "compiler_version": "14",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "15", "compiler_version": "15",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "16", "compiler_version": "16",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "17", "compiler_version": "17",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "18", "compiler_version": "18",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "19", "compiler_version": "19",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "debian", "distro_name": "debian",
"distro_version": "bookworm", "distro_version": "bookworm",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "20", "compiler_version": "20",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "8", "distro_version": "8",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14", "compiler_version": "14",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "8", "distro_version": "8",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "any", "compiler_version": "any",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "9", "distro_version": "9",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "12", "compiler_version": "12",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "9", "distro_version": "9",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "13", "compiler_version": "13",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "9", "distro_version": "9",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14", "compiler_version": "14",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "9", "distro_version": "9",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "any", "compiler_version": "any",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "10", "distro_version": "10",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14", "compiler_version": "14",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "rhel", "distro_name": "rhel",
"distro_version": "10", "distro_version": "10",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "any", "compiler_version": "any",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "jammy", "distro_version": "jammy",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "12", "compiler_version": "12",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "13", "compiler_version": "13",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "gcc", "compiler_name": "gcc",
"compiler_version": "14", "compiler_version": "14",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "16", "compiler_version": "16",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "17", "compiler_version": "17",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "18", "compiler_version": "18",
"image_sha": "97ba375" "image_sha": "edf4576"
}, },
{ {
"distro_name": "ubuntu", "distro_name": "ubuntu",
"distro_version": "noble", "distro_version": "noble",
"compiler_name": "clang", "compiler_name": "clang",
"compiler_version": "19", "compiler_version": "19",
"image_sha": "97ba375" "image_sha": "edf4576"
} }
], ],
"build_type": ["Debug", "Release"], "build_type": ["Debug", "Release"],

View File

@@ -11,17 +11,21 @@ tools.info.package_ids:confs+=["user.package:sanitizers"]
{% if compiler == "gcc" %} {% if compiler == "gcc" %}
{% if sanitizers == "Address" %} {% if sanitizers == "Address" %}
rippled:tools.build:cxxflags+=['-fsanitize=address,undefined,float-divide-by-zero,signed-integer-overflow'] tools.build:cxxflags+=['-fsanitize=address,undefined,float-divide-by-zero,signed-integer-overflow
-fno-omit-frame-pointer -O1']
{% elif sanitizers == "Thread" %} {% elif sanitizers == "Thread" %}
rippled:tools.build:cxxflags+=['-fsanitize=thread,undefined,float-divide-by-zero,signed-integer-overflow'] tools.build:cxxflags+=['-fsanitize=thread,undefined,float-divide-by-zero,signed-integer-overflow -fno-omit-frame-pointer
-O1']
{% endif %} {% endif %}
{% else %} {% elif compiler == "clang" %}
{% if sanitizers == "Address" %} {% if sanitizers == "Address" %}
rippled:tools.build:cxxflags+=['-fsanitize=address,undefined,float-divide-by-zero,signed-integer-overflow,unsigned-integer-overflow'] tools.build:cxxflags+=['-fsanitize=address,undefined,float-divide-by-zero,signed-integer-overflow,unsigned-integer-overflow
-fno-omit-frame-pointer -O1']
{% elif sanitizers == "Thread" %} {% elif sanitizers == "Thread" %}
rippled:tools.build:cxxflags+=['-fsanitize=thread,undefined,float-divide-by-zero,signed-integer-overflow,unsigned-integer-overflow'] tools.build:cxxflags+=['-fsanitize=thread,undefined,float-divide-by-zero,signed-integer-overflow,unsigned-integer-overflow
-fno-omit-frame-pointer -O1']
{% endif %} {% endif %}
{% endif %} {% endif %}