Skip to content
Merged
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
69 changes: 69 additions & 0 deletions .github/workflows/cmake_ubuntu_sanitizers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: cmake Ubuntu Sanitizers

on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Debug

jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04]
sanitizer: [asan_ubsan, tsan]

steps:
- uses: actions/checkout@v2

- name: Install Conan
id: conan
uses: turtlebrowser/get-conan@main

- name: Create default profile
run: conan profile detect

- name: Install conan dependencies
run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing

- name: Normalize build type
shell: bash
# The build type is Capitalized, e.g. Release, but the preset is all lowercase, e.g. release.
# There is no built in way to do string manipulations on GHA as far as I know.`
run: echo "BUILD_TYPE_LOWERCASE=$(echo "${BUILD_TYPE}" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV

- name: Configure CMake
shell: bash
run: |
if [[ "${{ matrix.sanitizer }}" == "asan_ubsan" ]]; then
cmake --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} \
-DBTCPP_ENABLE_ASAN:BOOL=ON -DBTCPP_ENABLE_UBSAN:BOOL=ON
else
cmake --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} \
-DBTCPP_ENABLE_TSAN:BOOL=ON
fi

- name: Build
shell: bash
run: cmake --build --preset conan-${{ env.BUILD_TYPE_LOWERCASE }}

- name: run test (Linux + Address and Undefined Behavior Sanitizers)
env:
GTEST_COLOR: "On"
ASAN_OPTIONS: "color=always"
UBSAN_OPTIONS: "halt_on_error=1:print_stacktrace=1:color=always"
TSAN_OPTIONS: "color=always"
# There is a known issue with TSAN on recent kernel versions. Without the vm.mmap_rnd_bits=28
# workaround all binaries with TSan enabled crash with "FATAL: ThreadSanitizer: unexpected memory mapping"
run: sudo sysctl vm.mmap_rnd_bits=28 && ctest --test-dir build/${{env.BUILD_TYPE}} --output-on-failure
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ option(BTCPP_EXAMPLES "Build tutorials and examples" ON)
option(BUILD_TESTING "Build the unit tests" ON)
option(BTCPP_GROOT_INTERFACE "Add Groot2 connection. Requires ZeroMQ" ON)
option(BTCPP_SQLITE_LOGGING "Add SQLite logging." ON)
option(BTCPP_ENABLE_ASAN "Enable Address Sanitizer" OFF)
option(BTCPP_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
option(BTCPP_ENABLE_TSAN "Enable Thread Sanitizer" OFF)

option(USE_V3_COMPATIBLE_NAMES "Use some alias to compile more easily old 3.x code" OFF)
option(ENABLE_FUZZING "Enable fuzzing builds" OFF)
Expand Down Expand Up @@ -54,6 +57,8 @@ endif()
set(CMAKE_CONFIG_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CONFIG_PATH}")

include(sanitizers)

set(BTCPP_LIBRARY ${PROJECT_NAME})

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
Expand Down
30 changes: 30 additions & 0 deletions cmake/sanitizers.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
if(BTCPP_ENABLE_ASAN OR BTCPP_ENABLE_UBSAN OR BTCPP_ENABLE_TSAN)
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug|RelWithDebInfo")
message(FATAL_ERROR "Sanitizers require debug symbols. Please set CMAKE_BUILD_TYPE to Debug or RelWithDebInfo.")
endif()
add_compile_options(-fno-omit-frame-pointer)
endif()

# Address Sanitizer and Undefined Behavior Sanitizer can be run at the same time.
# Thread Sanitizer requires its own build.
if(BTCPP_ENABLE_TSAN AND (BTCPP_ENABLE_ASAN OR BTCPP_ENABLE_UBSAN))
message(FATAL_ERROR "TSan is not compatible with ASan or UBSan. ASan and UBSan can run together, but TSan requires its own separate build.")
endif()

if(BTCPP_ENABLE_ASAN)
message(STATUS "Address Sanitizer enabled")
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
endif()

if(BTCPP_ENABLE_UBSAN)
message(STATUS "Undefined Behavior Sanitizer enabled")
add_compile_options(-fsanitize=undefined)
add_link_options(-fsanitize=undefined)
endif()

if(BTCPP_ENABLE_TSAN)
message(STATUS "Thread Sanitizer enabled")
add_compile_options(-fsanitize=thread)
add_link_options(-fsanitize=thread)
endif()
16 changes: 14 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,28 @@ if(ament_cmake_FOUND)

else()

enable_testing()

find_package(GTest REQUIRED)
include(GoogleTest)

enable_testing()
add_executable(behaviortree_cpp_test ${BT_TESTS})
add_test(NAME btcpp_test COMMAND behaviortree_cpp_test)

target_link_libraries(behaviortree_cpp_test
GTest::gtest
GTest::gtest_main)

# gtest_discover_tests queries the test executable for available tests and registers them on ctest individually
# On Windows it needs a little help to find the shared libraries
if(WIN32)
gtest_discover_tests(behaviortree_cpp_test
DISCOVERY_MODE PRE_TEST
DISCOVERY_ENVIRONMENT "PATH=$<TARGET_FILE_DIR:behaviortree_cpp_test>;$ENV{PATH}"
)
else()
gtest_discover_tests(behaviortree_cpp_test)
endif()

endif()

target_include_directories(behaviortree_cpp_test PRIVATE include)
Expand Down
Loading