Skip to content
Open
Show file tree
Hide file tree
Changes from 14 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
152 changes: 152 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,157 @@ jobs:
USE_BAZEL_VERSION: "7.4.1"
run: bazel test //...

sanitizers:
needs: [preflight-check]
# needs: [preflight-check, static-code-analysis, cargo-nextest]
if: ${{ needs.changes.outputs.source-code == 'true' }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
toolchain: [stable] # Rust sanitizers require nightly
sanitizer: ["address", "ub", "address;ub", "thread"]
exclude:
# Only run address sanitizer on macOS
- os: macos-latest
sanitizer: "thread"
- os: macos-latest
sanitizer: "ub"
- os: macos-latest
sanitizer: "address;ub"
timeout-minutes: 60
runs-on: ${{ matrix.os }}
env:
RUST_BACKTRACE: 1
steps:
- name: Checkout sources
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4

- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: "3.31.x"

- name: Use cmake
run: cmake --version

- name: Setup Rust
uses: dtolnay/rust-toolchain@888c2e1ea69ab0d4330cbf0af1ecc7b68f368cc1 # ratchet:dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.toolchain }}
components: rustfmt, clippy
# targets: x86_64-unknown-linux-gnu, x86_64-apple-darwin

- name: Download artifact cargo-nextest
uses: ./.github/actions/download-cached-rust-tool
with:
artifact-bin-name: cargo-nextest
artifact-upload-name: ${{ runner.os }}-cargo-nextest

- name: Prepare Linux
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
internal/scripts/ci_prepare_ubuntu.sh
uname -a

# - name: Set Rust sanitizer flags
# run: |
# # Set default target based on OS
# if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then
# RUST_TARGET="x86_64-unknown-linux-gnu"
# elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then
# RUST_TARGET="x86_64-apple-darwin"
# fi

# # Set sanitizer-specific flags
# if [[ "${{ matrix.sanitizer }}" == "address" ]]; then
# echo "RUSTFLAGS=-Zsanitizer=address -Copt-level=1" >> $GITHUB_ENV
# elif [[ "${{ matrix.sanitizer }}" == "ub" ]]; then
# # Rust doesn't have a specific undefined behavior sanitizer, but we can enable debug assertions
# echo "RUSTFLAGS=-Cdebug-assertions=on -Coverflow-checks=on -Copt-level=1" >> $GITHUB_ENV
# elif [[ "${{ matrix.sanitizer }}" == "address;ub" ]]; then
# echo "RUSTFLAGS=-Zsanitizer=address -Cdebug-assertions=on -Coverflow-checks=on -Copt-level=1" >> $GITHUB_ENV
# elif [[ "${{ matrix.sanitizer }}" == "thread" ]]; then
# echo "RUSTFLAGS=-Zsanitizer=thread -Copt-level=1" >> $GITHUB_ENV
# fi

# echo "RUST_TARGET=$RUST_TARGET" >> $GITHUB_ENV

- name: Run cargo build
run: cargo build --workspace --all-targets

- name: Run cargo nextest
run: cargo nextest run --workspace --all-targets --no-fail-fast

- name: Build iceoryx_hoofs
run: internal/scripts/ci_build_and_install_iceoryx_hoofs.sh

- name: Build language bindings with sanitizers
run: |
cmake -S . -B target/ff/cc/build \
-DBUILD_EXAMPLES=ON \
-DBUILD_TESTING=ON \
-DCMAKE_BUILD_TYPE=Debug \
-DSANITIZERS="${{ matrix.sanitizer }}" \
-DCMAKE_INSTALL_PREFIX=target/ff/cc/install \
-DCMAKE_PREFIX_PATH="${{ github.workspace }}/target/ff/iceoryx/install" \
-DRUST_BUILD_ARTIFACT_PATH="${{ github.workspace }}/target/debug"
cmake --build target/ff/cc/build
cmake --install target/ff/cc/build

- name: Run C language binding tests with sanitizers
env:
ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0"
LSAN_OPTIONS: "verbosity=1:log_threads=1"
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
TSAN_OPTIONS: "halt_on_error=1:history_size=7"
run: target/ff/cc/build/tests/iceoryx2-c-tests

- name: Run C++ language binding tests with sanitizers
env:
ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0"
LSAN_OPTIONS: "verbosity=1:log_threads=1"
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
TSAN_OPTIONS: "halt_on_error=1:history_size=7"
run: target/ff/cc/build/tests/iceoryx2-cxx-tests

# - name: Run C examples with sanitizers
# env:
# ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0"
# LSAN_OPTIONS: "verbosity=1:log_threads=1"
# UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
# TSAN_OPTIONS: "halt_on_error=1:history_size=7"
# run: |
# cd target/ff/cc/build/examples/c
# find . -maxdepth 1 -type f -executable | while read example; do
# echo "Running C example: $example"
# timeout 10s $example || true
# done

# - name: Run C++ examples with sanitizers
# env:
# ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0"
# LSAN_OPTIONS: "verbosity=1:log_threads=1"
# UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
# TSAN_OPTIONS: "halt_on_error=1:history_size=7"
# run: |
# cd target/ff/cc/build/examples/cxx
# find . -maxdepth 1 -type f -executable | while read example; do
# echo "Running C++ example: $example"
# timeout 10s $example || true
# done

- name: Run end-to-end tests with sanitizers
# Skip end-to-end tests with thread sanitizer due to potential issues with dynamic linking
if: ${{ matrix.sanitizer != 'thread' }}
env:
ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0"
LSAN_OPTIONS: "verbosity=1:log_threads=1"
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
TSAN_OPTIONS: "halt_on_error=1:history_size=7"
run: |
cd "${GITHUB_WORKSPACE}"
internal/scripts/ci_build_and_run_end_to_end_tests.sh no-build

cargo-publish-dry-run:
needs: [preflight-check, static-code-analysis]
if: ${{ needs.changes.outputs.source-code == 'true' }}
Expand Down Expand Up @@ -792,6 +943,7 @@ jobs:
x86_32,
python-bindings,
end-to-end-tests,
sanitizers,
]
runs-on: ubuntu-latest
steps:
Expand Down
2 changes: 2 additions & 0 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
[#1133](https://github.com/eclipse-iceoryx/iceoryx2/issues/1133)
* Enable -Wconversion warning for the C and C++ code
[#956](https://github.com/eclipse-iceoryx/iceoryx2/issues/956)
* Add thread sanitizer
[#957](https://github.com/eclipse-iceoryx/iceoryx2/issues/957)

### Workflow

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ if(NOT ICEORYX2_COMMON_OPTIONS_AND_PARAMS_LISTED)
DEFAULT_VALUE OFF
)

add_option(
add_param(
NAME SANITIZERS
DESCRIPTION "Build with undefined-behavior- and address-sanitizer"
DEFAULT_VALUE OFF
DESCRIPTION "Sanitizer configuration: 'address', 'ub', 'address;ub', 'thread', or empty string (disabled)"
DEFAULT_VALUE ""
)

add_option(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ endmacro()
macro(add_param)
set(ONE_VALUE_ARGS NAME DESCRIPTION DEFAULT_VALUE)
cmake_parse_arguments(ADD_PARAM "" "${ONE_VALUE_ARGS}" "" ${ARGN})
if(NOT ${ADD_PARAM_NAME})
if(NOT DEFINED ${ADD_PARAM_NAME})
set(${ADD_PARAM_NAME} ${ADD_PARAM_DEFAULT_VALUE})
endif()
message(STATUS " ${ADD_PARAM_NAME}: ${${ADD_PARAM_NAME}} (Description: ${ADD_PARAM_DESCRIPTION})")
Expand Down
18 changes: 16 additions & 2 deletions iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,19 @@
#
# SPDX-License-Identifier: Apache-2.0 OR MIT

# TODO #957: differentiate between address and thread sanitizer
set(ICEORYX2_SANITZER_FLAGS -fsanitize=address -fsanitize=undefined CACHE INTERNAL "")
# Parse SANITIZERS string and set appropriate flags
set(ICEORYX2_SANITIZER_FLAGS "" CACHE INTERNAL "")

if(NOT DEFINED SANITIZERS OR SANITIZERS STREQUAL "")
# No sanitizers enabled - empty string is the default
elseif(SANITIZERS STREQUAL "address")
set(ICEORYX2_SANITIZER_FLAGS -fsanitize=address CACHE INTERNAL "")
elseif(SANITIZERS STREQUAL "ub")
set(ICEORYX2_SANITIZER_FLAGS -fsanitize=undefined CACHE INTERNAL "")
elseif(SANITIZERS STREQUAL "address;ub")
set(ICEORYX2_SANITIZER_FLAGS -fsanitize=address -fsanitize=undefined CACHE INTERNAL "")
elseif(SANITIZERS STREQUAL "thread")
set(ICEORYX2_SANITIZER_FLAGS -fsanitize=thread CACHE INTERNAL "")
else()
message(FATAL_ERROR "Invalid SANITIZERS value: '${SANITIZERS}'. Valid options are: 'address', 'ub', 'address;ub', 'thread', or empty string (disabled)")
endif()
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,18 @@ if(WARNING_AS_ERROR)
set(ICEORYX2_CXX_WARNINGS ${ICEORYX2_CXX_WARNINGS} -Werror CACHE INTERNAL "")
endif()

set(ICEORYX2_SANITZER_FLAGS CACHE INTERNAL "")
if(SANITIZERS)
set(ICEORYX2_SANITIZER_FLAGS CACHE INTERNAL "")
set(ICEORYX2_LINK_FLAGS CACHE INTERNAL "")

if(DEFINED SANITIZERS AND NOT SANITIZERS STREQUAL "")
include(Iceoryx2Sanitizer)

set(ICEORYX2_C_FLAGS ${ICEORYX2_C_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")
set(ICEORYX2_CXX_FLAGS ${ICEORYX2_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")
set(ICEORYX2_TEST_CXX_FLAGS ${ICEORYX2_TEST_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")

# Sanitizer flags must also be added to linker flags
set(ICEORYX2_LINK_FLAGS ${ICEORYX2_LINK_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

todo: this can be removed, after fixing the typo the linker already includes sanitizer flags

endif()

set(ICEORYX2_COVERAGE_FLAGS CACHE INTERNAL "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ if(WARNING_AS_ERROR)
set(ICEORYX2_CXX_WARNINGS ${ICEORYX2_CXX_WARNINGS} -Werror CACHE INTERNAL "")
endif()

if(SANITIZERS)
set(ICEORYX2_LINK_FLAGS CACHE INTERNAL "")

if(DEFINED SANITIZERS AND NOT SANITIZERS STREQUAL "")
include(Iceoryx2Sanitizer)

set(ICEORYX2_CXX_FLAGS "${ICEORYX2_CXX_FLAGS} ${ICEORYX2_SANITZER_FLAGS}" CACHE INTERNAL "")
set(ICEORYX2_TEST_CXX_FLAGS "${ICEORYX2_TEST_CXX_FLAGS} ${ICEORYX2_SANITZER_FLAGS}" CACHE INTERNAL "")
set(ICEORYX2_C_FLAGS ${ICEORYX2_C_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")
set(ICEORYX2_CXX_FLAGS ${ICEORYX2_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")
set(ICEORYX2_TEST_CXX_FLAGS ${ICEORYX2_TEST_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")

# Sanitizer flags must also be added to linker flags
set(ICEORYX2_LINK_FLAGS ${ICEORYX2_LINK_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "")
endif()
Loading