From 7617072ebcd8b316392c485f6193fb84a05479d0 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde Date: Fri, 28 Nov 2025 16:01:01 +0000 Subject: [PATCH] sanitizer variable now has separate address,undefined and thread values Signed-off-by: Pratik Mankawde --- .github/scripts/strategy-matrix/generate.py | 4 +- .../workflows/reusable-build-test-config.yml | 2 +- BUILD.md | 9 ++- conan/profiles/sanitizers | 74 +++++++++++++------ docs/build/sanitizers.md | 14 +++- 5 files changed, 70 insertions(+), 33 deletions(-) diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index b930359c33..bf6f1f806f 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -258,7 +258,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: "build_type": build_type, "os": os, "architecture": architecture, - "sanitizers": "Address", + "sanitizers": "Address,UndefinedBehavior", } ) if "tsan_ubsan" in configs: @@ -271,7 +271,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: "build_type": build_type, "os": os, "architecture": architecture, - "sanitizers": "Thread", + "sanitizers": "Thread,UndefinedBehavior", } ) else: diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index 69a59573e7..64d332f4b6 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -51,7 +51,7 @@ on: default: 2 sanitizers: - description: "The sanitizers to enable ('Address+UndefinedBehaviour' or 'Thread+UndefinedBehaviour')." + description: "The sanitizers to enable ('Address+UndefinedBehavior' or 'Thread+UndefinedBehavior')." required: false type: string default: "" diff --git a/BUILD.md b/BUILD.md index e1e93e3f42..d2e2bca9c6 100644 --- a/BUILD.md +++ b/BUILD.md @@ -367,15 +367,18 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS'] conan install .. --output-folder . --build missing --settings build_type=Debug ``` - If you would like to activate `asan+ubsan`(`Address`) or `tsan+ubsan`(`Thread`) for the build, - declare an environment variable as follows and use the `sanitizers` + If you would like to activate `asan`(`Address`) or `tsan`(`Thread`) or `ubsan`(`UndefinedBehavior`) for the build, + declare an environment variable as follows(with values: `Address`, `Thread`, `UndefinedBehavior`) and use the `sanitizers` profile in the `conan install` command. ``` SANITIZERS=Address conan install .. --output-folder . --profile:all sanitizers --build missing --settings build_type=Debug + # or if you want asan+ubsan + SANITIZERS=Address,UndefinedBehavior conan install .. --output-folder . --profile:all sanitizers --build missing --settings build_type=Debug ``` - Available options for SANITIZERS: `Address` and `Thread` + Note: Do not mix Address and Thread, that's incompatible. + More details here: [sanitizers](./docs/build/sanitizers.md) To build Debug, in the next step, be sure to set `-DCMAKE_BUILD_TYPE=Debug` diff --git a/conan/profiles/sanitizers b/conan/profiles/sanitizers index a1db42b511..9d8fe6ef5f 100644 --- a/conan/profiles/sanitizers +++ b/conan/profiles/sanitizers @@ -1,32 +1,58 @@ include(default) {% set compiler, version, compiler_exe = detect_api.detect_default_compiler() %} -{% set default_sanitizer_flags = "undefined,float-divide-by-zero" %} {% set sanitizers = os.getenv("SANITIZERS") %} [conf] -{% if compiler == "gcc" %} - {% set asan_sanitizer_flags = "-fsanitize=address,"~default_sanitizer_flags~" -mcmodel=large -fno-PIC" %} - {% set tsan_sanitizer_flags = "-fsanitize=thread,"~default_sanitizer_flags~" -mcmodel=medium -fno-PIC" %} - {% if sanitizers == "Address" %} - tools.build:cxxflags+=['{{asan_sanitizer_flags}} -fno-omit-frame-pointer -O1 -Wno-stringop-overflow'] - tools.build:sharedlinkflags+=['{{asan_sanitizer_flags}}'] - tools.build:exelinkflags+=['{{asan_sanitizer_flags}}'] - {% elif sanitizers == "Thread" %} - tools.build:cxxflags+=['{{tsan_sanitizer_flags}} -fno-omit-frame-pointer -O1 -Wno-stringop-overflow -Wno-tsan'] - tools.build:sharedlinkflags+=['{{tsan_sanitizer_flags}}'] - tools.build:exelinkflags+=['{{tsan_sanitizer_flags}}'] - {% endif %} -{% elif compiler == "apple-clang" or compiler == "clang" %} - {% set asan_sanitizer_flags = "-fsanitize=address,"~default_sanitizer_flags~",unsigned-integer-overflow -fno-PIC" %} - {% set tsan_sanitizer_flags = "-fsanitize=thread,"~default_sanitizer_flags~",unsigned-integer-overflow -fno-PIC" %} - {% if sanitizers == "Address" %} - tools.build:cxxflags+=['{{asan_sanitizer_flags}} -fno-omit-frame-pointer -O1'] - tools.build:sharedlinkflags+=['{{asan_sanitizer_flags}}'] - tools.build:exelinkflags+=['{{asan_sanitizer_flags}}'] - {% elif sanitizers == "Thread" %} - tools.build:cxxflags+=['{{tsan_sanitizer_flags}} -fno-omit-frame-pointer -O1'] - tools.build:sharedlinkflags+=['{{tsan_sanitizer_flags}}'] - tools.build:exelinkflags+=['{{tsan_sanitizer_flags}}'] +{% if sanitizers %} + {% if compiler == "gcc" %} + {% if "Address" in sanitizers or "Thread" in sanitizers or "UndefinedBehavior" in sanitizers %} + {% set sanitizer_list = [] %} + {% set model_code = "" %} + {% set extra_cxxflags = "-fno-omit-frame-pointer -fno-PIC -O1 -Wno-stringop-overflow" %} + + {% if "Address" in sanitizers %} + {% set _ = sanitizer_list.append("address") %} + {% set model_code = "-mcmodel=large" %} + {% elif "Thread" in sanitizers %} + {% set _ = sanitizer_list.append("thread") %} + {% set model_code = "-mcmodel=medium" %} + {% set extra_cxxflags = extra_cxxflags ~ " -Wno-tsan" %} + {% endif %} + + {% if "UndefinedBehavior" in sanitizers or "UndefinedBehavior" in sanitizers %} + {% set _ = sanitizer_list.append("undefined") %} + {% set _ = sanitizer_list.append("float-divide-by-zero") %} + {% endif %} + + {% set sanitizer_flags = "-fsanitize=" ~ ",".join(sanitizer_list) ~ " " ~ model_code %} + + tools.build:cxxflags+=['{{sanitizer_flags}} {{extra_cxxflags}}'] + tools.build:sharedlinkflags+=['{{sanitizer_flags}}'] + tools.build:exelinkflags+=['{{sanitizer_flags}}'] + {% endif %} + {% elif compiler == "apple-clang" or compiler == "clang" %} + {% if "Address" in sanitizers or "Thread" in sanitizers or "UndefinedBehavior" in sanitizers %} + {% set sanitizer_list = [] %} + {% set extra_cxxflags = "-fno-omit-frame-pointer -fno-PIC -O1" %} + + {% if "Address" in sanitizers %} + {% set _ = sanitizer_list.append("address") %} + {% elif "Thread" in sanitizers %} + {% set _ = sanitizer_list.append("thread") %} + {% endif %} + + {% if "UndefinedBehavior" in sanitizers %} + {% set _ = sanitizer_list.append("undefined") %} + {% set _ = sanitizer_list.append("float-divide-by-zero") %} + {% set _ = sanitizer_list.append("unsigned-integer-overflow") %} + {% endif %} + + {% set sanitizer_flags = "-fsanitize=" ~ ",".join(sanitizer_list) %} + + tools.build:cxxflags+=['{{sanitizer_flags}} {{extra_cxxflags}}'] + tools.build:sharedlinkflags+=['{{sanitizer_flags}}'] + tools.build:exelinkflags+=['{{sanitizer_flags}}'] + {% endif %} {% endif %} {% endif %} diff --git a/docs/build/sanitizers.md b/docs/build/sanitizers.md index 89013030c0..1ce79ed62e 100644 --- a/docs/build/sanitizers.md +++ b/docs/build/sanitizers.md @@ -7,6 +7,7 @@ Corresponding suppression files are located in the `sanitizers/suppressions` dir - [Building with Sanitizers](#building-with-sanitizers) - [AddressSanitizer (ASan) + UndefinedBehaviorSanitizer (UBSan)](#addresssanitizer-asan--undefinedbehaviorsanitizer-ubsan) - [ThreadSanitizer (TSan) + UndefinedBehaviorSanitizer (UBSan)](#threadsanitizer-tsan--undefinedbehaviorsanitizer-ubsan) + - [Just UndefinedBehaviorSanitizer (UBSan)](#just-undefinedbehaviorsanitizer-ubsan) - [Running Tests with Sanitizers](#running-tests-with-sanitizers) - [AddressSanitizer (ASan)](#addresssanitizer-asan) - [ThreadSanitizer (TSan)](#threadsanitizer-tsan) @@ -43,17 +44,24 @@ Follow the same instructions as mentioned in [BUILD.md](../../BUILD.md) but with #### AddressSanitizer (ASan) + UndefinedBehaviorSanitizer (UBSan) -Build with AddressSanitizer. This also builds rippled with UndefinedBehavior sanitizer. +Build with AddressSanitizer+UndefinedBehavior sanitizers (or you can choose just one of them). ```bash -SANITIZERS=Address conan install .. --output-folder . --profile sanitizers --build missing --settings build_type=Release +SANITIZERS=Address,UndefinedBehavior conan install .. --output-folder . --profile sanitizers --build missing --settings build_type=Release ``` #### ThreadSanitizer (TSan) + UndefinedBehaviorSanitizer (UBSan) ```bash # Build dependencies with Thread sanitizer -SANITIZERS=Thread conan install .. --output-folder . --profile sanitizers --build missing --settings build_type=Release +SANITIZERS=Thread,UndefinedBehavior conan install .. --output-folder . --profile sanitizers --build missing --settings build_type=Release +``` + +#### Just UndefinedBehaviorSanitizer (UBSan) + +```bash +# Build dependencies with Thread sanitizer +SANITIZERS=UndefinedBehavior conan install .. --output-folder . --profile sanitizers --build missing --settings build_type=Release ``` Use `--profile:all sanitizers` if you would like to build all dependencies and libraries (boost etc.) with sanitizers. This might take long time but you won't see some false-positives on sanitizer reports since whole binary will be instrumented.