Skip to content

Commit

Permalink
iox-eclipse-iceoryx#141 enable sanizier(-fsanitize=address)
Browse files Browse the repository at this point in the history
Signed-off-by: Prasanna Bhat <prasanna.yoga@gmail.com>
  • Loading branch information
prasannabhat committed Nov 30, 2020
1 parent 65445be commit 6521f9f
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 31 deletions.
7 changes: 0 additions & 7 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,6 @@ jobs:
cd $GITHUB_WORKSPACE/build
../tools/run_all_tests.sh
- name : Build sources (clang)
run: |
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
export NUM_CORES=`nproc`
$GITHUB_WORKSPACE/tools/iceoryx_build_test.sh build-test with-dds-gateway clean strict -j $NUM_CORES
# This job builds & runs iceoryx tests in macos-10.15
macos-build-script:
runs-on: macos-10.15
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/sanitize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This workflow builds & runs test cases in iceoryx

name: Sanitize

# Triggers the workflow on push or pull request events but only for the master branch
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
clang-sanitize:
# The type of runner that the job will run on
runs-on: ubuntu-18.04

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Install iceoryx dependencies
# Softwares installed in ubuntu-18.04 instance
# https://github.com/actions/virtual-environments/blob/master/images/linux/Ubuntu1804-README.md
run: sudo apt-get update && sudo apt-get install -y libacl1-dev libncurses5-dev

- name : Checkout
uses: actions/checkout@v2

- name : Clang Sanitize
run: |
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
export NUM_CORES=`nproc`
# build tests , dont run them
$GITHUB_WORKSPACE/tools/iceoryx_build_test.sh build-test sanitize clean -j $NUM_CORES
cd $GITHUB_WORKSPACE/build
# Run tests , continue execution on error (to get maximum failures)
../tools/run_all_tests.sh continue-on-error

14 changes: 14 additions & 0 deletions iceoryx_meta/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ option(examples "build with iceoryx examples" ON)
option(introspection "builds the introspection client which requires the ncurses library with an activated terminfo feature" OFF)
option(dds_gateway "builds the iceoryx dds gateway - enables internode communication via dds" OFF)
option(binding_c "builds the C language bindings" ON)
option(sanitize "Build with sanitizers" OFF)

# ===== Dependencies
if(TOML_CONFIG)
Expand All @@ -43,6 +44,18 @@ if(coverage)
endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif(coverage)

if(sanitize)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(SANITIZE_BLACKLIST -fsanitize-blacklist=${CMAKE_CURRENT_SOURCE_DIR}/sanitizer_blacklist.txt)
endif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(SANITIZE_COMPILE_FLAGS -fsanitize=address ${SANITIZE_BLACKLIST} -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -O1)
set(SANITIZE_LINK_FLAGS "-g -fsanitize=address")
else(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
message( FATAL_ERROR "You need to run sanitize with gcc/clang compiler." )
endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
endif(sanitize)


if(test)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/googletest ${CMAKE_BINARY_DIR}/dependencies/googletest/prebuild)
Expand Down Expand Up @@ -127,5 +140,6 @@ message(" Build Properties")
message(" project name..............: " ${CMAKE_PROJECT_NAME})
message(" c compiler................: " ${CMAKE_C_COMPILER})
message(" c++ compiler..............: " ${CMAKE_CXX_COMPILER})
message(" c++ flags.................: " ${CMAKE_CXX_FLAGS})
message("")

9 changes: 9 additions & 0 deletions iceoryx_meta/sanitizer_blacklist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Suppress specific errors
src:iceoryx_binding_c/test/integrationtests/test_wait_set.cpp
src:*test_wait_set.cpp
src:*test_wait_set.cpp*
# fun:*iox::posix::MessageQueue::receive*
src:*message_queue.cpp*
fun:*MessageQueue::receive*
fun:*IpcChannel_test_sendAndReceive_Test<iox::posix::MessageQueue>::TestBody*

8 changes: 4 additions & 4 deletions iceoryx_posh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ target_link_libraries(iceoryx_posh
${CMAKE_THREAD_LIBS_INIT}
)

target_compile_options(iceoryx_posh PRIVATE ${ICEORYX_WARNINGS})
target_compile_options(iceoryx_posh PRIVATE ${ICEORYX_WARNINGS} ${SANITIZE_COMPILE_FLAGS})

if(LINUX)
target_link_libraries(iceoryx_posh PRIVATE rt )
Expand Down Expand Up @@ -183,7 +183,7 @@ target_link_libraries(iceoryx_posh_gateway
iceoryx_posh::iceoryx_posh
)

target_compile_options(iceoryx_posh_gateway PRIVATE ${ICEORYX_WARNINGS})
target_compile_options(iceoryx_posh_gateway PRIVATE ${ICEORYX_WARNINGS} ${SANITIZE_COMPILE_FLAGS})

#
########## posh roudi lib ##########
Expand Down Expand Up @@ -242,7 +242,7 @@ if(CMAKE_SYSTEM_NAME MATCHES QNX)
target_link_libraries(iceoryx_posh_roudi PRIVATE socket)
endif(CMAKE_SYSTEM_NAME MATCHES QNX)

target_compile_options(iceoryx_posh_roudi PRIVATE ${ICEORYX_WARNINGS})
target_compile_options(iceoryx_posh_roudi PRIVATE ${ICEORYX_WARNINGS} ${SANITIZE_COMPILE_FLAGS})

if(TOML_CONFIG)
if ( NOT cpptoml_FOUND )
Expand Down Expand Up @@ -284,7 +284,7 @@ if(TOML_CONFIG)
cpptoml
)

target_compile_options(iceoryx_posh_config PRIVATE ${ICEORYX_WARNINGS})
target_compile_options(iceoryx_posh_config PRIVATE ${ICEORYX_WARNINGS} ${SANITIZE_COMPILE_FLAGS})

#
######### posh roudi daemon ##########
Expand Down
4 changes: 2 additions & 2 deletions iceoryx_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ if(PERFORM_CLANG_TIDY)
endif(PERFORM_CLANG_TIDY)


target_link_libraries(iceoryx_utils PUBLIC iceoryx_utils::iceoryx_platform)
target_link_libraries(iceoryx_utils PUBLIC iceoryx_utils::iceoryx_platform ${SANITIZE_LINK_FLAGS})

target_compile_options(iceoryx_utils PRIVATE ${ICEORYX_WARNINGS})
target_compile_options(iceoryx_utils PRIVATE ${ICEORYX_WARNINGS} ${SANITIZE_COMPILE_FLAGS})

# TODO: Make ICEORYX::UTILS private???
target_include_directories(iceoryx_utils
Expand Down
11 changes: 11 additions & 0 deletions sanitize_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

# cd build/binding_c/test
# ./binding_c_integrationtests --gtest_filter="*iox_ws_test*" 2>&1 | tee log_file_ignore.txt
# code log_file_ignore.txt
# cd ../../..

cd build/utils/test
./utils_moduletests --gtest_filter="*IpcChannel_test*" 2>&1 | tee log_func_ignore.txt
code log_func_ignore.txt
cd ../../..
21 changes: 18 additions & 3 deletions tools/iceoryx_build_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ RUN_TEST=false
INTROSPECTION_FLAG="ON"
DDS_GATEWAY_FLAG="OFF"
ONE_TO_MANY_ONLY_FLAG="OFF"
SANITIZE_FLAG="OFF"

while (( "$#" )); do
case "$1" in
Expand Down Expand Up @@ -114,6 +115,13 @@ while (( "$#" )); do
ONE_TO_MANY_ONLY_FLAG="ON"
shift 1
;;
"sanitize")
echo "Build with sanitizers"
BUILD_TYPE="Debug"
TEST_FLAG="ON"
SANITIZE_FLAG="ON"
shift 1
;;
"help")
echo "Build script for iceoryx."
echo "By default, iceoryx, the dds gateway and the examples are built."
Expand All @@ -135,6 +143,7 @@ while (( "$#" )); do
echo " build-test Builds the tests (doesn't run)"
echo " skip-introspection Skips building iceoryx introspection"
echo " one-to-many Restricts to 1:n communication only"
echo " sanitize Build with sanitizers"
echo " help Prints this help"
echo ""
echo "e.g. iceoryx_build_test.sh -b ./build-scripted clean test release"
Expand Down Expand Up @@ -180,12 +189,15 @@ cd $BUILD_DIR
echo " [i] Current working directory: $(pwd)"

echo ">>>>>> Start building iceoryx package <<<<<<"
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_STRICT=$STRICT_FLAG -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX -DCMAKE_EXPORT_COMPILE_COMMANDS=$QACPP_JSON -DTOML_CONFIG=on -Dtest=$TEST_FLAG -Dcoverage=$COV_FLAG -Droudi_environment=on -Dexamples=OFF -Dintrospection=$INTROSPECTION_FLAG -Ddds_gateway=$DDS_GATEWAY_FLAG -Dbinding_c=ON -DONE_TO_MANY_ONLY=$ONE_TO_MANY_ONLY_FLAG $WORKSPACE/iceoryx_meta
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_STRICT=$STRICT_FLAG -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX -DCMAKE_EXPORT_COMPILE_COMMANDS=$QACPP_JSON -DTOML_CONFIG=on -Dtest=$TEST_FLAG -Dcoverage=$COV_FLAG -Droudi_environment=on -Dexamples=OFF -Dintrospection=$INTROSPECTION_FLAG -Ddds_gateway=$DDS_GATEWAY_FLAG -Dbinding_c=ON -DONE_TO_MANY_ONLY=$ONE_TO_MANY_ONLY_FLAG -Dsanitize=$SANITIZE_FLAG $WORKSPACE/iceoryx_meta
cmake --build . --target install -- -j$NUM_JOBS
echo ">>>>>> Finished building iceoryx package <<<<<<"

if [ "$COV_FLAG" == "OFF" ]
# Dont build examples when coverage or sanitization is enabled
if [ "$COV_FLAG" == "ON" ] || [ "$SANITIZE_FLAG" == "ON" ]
then
echo ">>>>>> Skip building iceoryx examples <<<<<<"
else
echo ">>>>>> Start building iceoryx examples <<<<<<"
cd $BUILD_DIR
mkdir -p iceoryx_examples
Expand All @@ -202,7 +214,10 @@ then
cmake -DCMAKE_PREFIX_PATH=$ICEORYX_INSTALL_PREFIX -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX $WORKSPACE/iceoryx_examples/iceperf
cmake --build . --target install -- -j$NUM_JOBS
echo ">>>>>> Finished building iceoryx examples <<<<<<"
else
fi

if [ "$COV_FLAG" == "ON" ]
then
$WORKSPACE/tools/gcov/lcov_generate.sh $WORKSPACE initial #make an initial scan to cover also files with no coverage
fi

Expand Down
83 changes: 68 additions & 15 deletions tools/run_all_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ COMPONENTS="utils posh binding_c"
GTEST_FILTER="*"
BASE_DIR=$PWD
GCOV_SCOPE="all"
CONTINUE_ON_ERROR=false

for arg in "$@"
do
Expand All @@ -33,6 +34,9 @@ do
"only-timing-tests")
GTEST_FILTER="*.TimingTest_*"
;;
"continue-on-error")
CONTINUE_ON_ERROR=true
;;
"all" | "component" | "unit" | "integration")
GCOV_SCOPE="$arg"
;;
Expand All @@ -46,6 +50,7 @@ do
echo " skip-dds-tests Skips tests for iceoryx_dds"
echo " disable-timing-tests Disables all timing tests"
echo " only-timing-tests Runs only timing tests"
echo " continue-on-error Continue execution upon error"
echo ""
exit -1
;;
Expand All @@ -66,29 +71,77 @@ mkdir -p "$TEST_RESULTS_DIR"

echo ">>>>>> Running Ice0ryx Tests <<<<<<"

set -e
if [ $CONTINUE_ON_ERROR == true ]
then
# Continue executing tests , when a test fails
set +e
else
# Stop executing tests , when a test fails
set -e
fi

failed_tests=0
execute_test () {
local component=$1
local test_scope=$2

case $test_scope in
"unit")
test_binary="$component"_moduletests
result_file="$component"_ModuleTestResults.xml
;;
"component")
test_binary="$component"_componenttests
result_file="$component"_ComponenttestTestResults.xml
;;
"integration")
test_binary="$component"_integrationtests
result_file="$component"_IntegrationTestResults.xml
;;
*)
echo "Wrong scope $test_scope!"
;;
esac

# Runs only tests available for the given component
if [ -f ./$test_binary ]; then
echo "Executing $test_binary"
./$test_binary --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULTS_DIR/$result_file"
fi

# return code from test application is non-zero -> some test cases failed
if [ $? != 0 ]; then
((failed_tests++))
echo "$test_scope test for $component failed!"
fi
}

for COMPONENT in $COMPONENTS; do
echo ""
echo "######################## executing moduletests & componenttests for $COMPONENT ########################"
echo "######################## executing tests for $COMPONENT ########################"
cd $BASE_DIR/$COMPONENT/test

# Runs only tests available for the given component

case $GCOV_SCOPE in
"unit" | "all")
[ -f ./"$COMPONENT"_moduletests ] && ./"$COMPONENT"_moduletests --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULTS_DIR/"$COMPONENT"_ModuleTestResults.xml"
;;
"component" | "all")
[ -f ./"$COMPONENT"_componenttests ] && ./"$COMPONENT"_componenttests --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULTS_DIR/"$COMPONENT"_ComponenttestTestResults.xml"
;;
"integration" | "all")
[ -f ./"$COMPONENT"_integrationtests ] && ./"$COMPONENT"_integrationtests --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULTS_DIR/"$COMPONENT"_IntegrationTestResults.xml"
;;
esac
if [ $GCOV_SCOPE == "unit" ] || [ $GCOV_SCOPE == "all" ]; then
execute_test $COMPONENT unit
fi
if [ $GCOV_SCOPE == "component" ] || [ $GCOV_SCOPE == "all" ]; then
execute_test $COMPONENT component
fi
if [ $GCOV_SCOPE == "integration" ] || [ $GCOV_SCOPE == "all" ]; then
execute_test $COMPONENT integration
fi
done

# do not start RouDi while the module and componenttests are running;
# they might do things which hurts RouDi, like in the roudi_shm test where named semaphores are opened and closed

if [ $failed_tests != 0 ]
then
echo "$failed_tests tests failed!"
fi
echo ">>>>>> Finished Running Iceoryx Tests <<<<<<"
# set return code to indicate test execution status (code = number of failed tests)
# this return code should not be interpreted as standard unix return code
exit $failed_tests


0 comments on commit 6521f9f

Please sign in to comment.