From 3e6546c65846983ff38a5b4e2394fae925e7311c Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 6 Jan 2017 13:54:32 -0800 Subject: [PATCH] Add Address Sanitizer support as build option. (#1114) - Add configure option for address sanitizer. - Add unit test for address sanitizer. - Enable address sanitizer support by default on distcheck. --- .travis.yml | 2 +- .travis/before_install.sh | 1 + .travis/script.sh | 2 ++ Makefile.am | 1 + configure.ac | 34 +++++++++++++++++++ examples/Makefile-posix | 2 -- tests/unit/Makefile.am | 22 ++++++++---- tests/unit/test_address_sanitizer.cpp | 49 +++++++++++++++++++++++++++ 8 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 tests/unit/test_address_sanitizer.cpp diff --git a/.travis.yml b/.travis.yml index c8822ff00..73759c910 100644 --- a/.travis.yml +++ b/.travis.yml @@ -81,7 +81,7 @@ matrix: - g++-6 - env: BUILD_TARGET="posix-distcheck" VERBOSE=1 os: linux - compiler: gcc + compiler: clang - env: BUILD_TARGET="posix-32-bit" VERBOSE=1 os: linux compiler: gcc diff --git a/.travis/before_install.sh b/.travis/before_install.sh index 40bac8c03..81f43523d 100755 --- a/.travis/before_install.sh +++ b/.travis/before_install.sh @@ -89,6 +89,7 @@ cd /tmp || die [ $BUILD_TARGET != posix-distcheck ] || { sudo apt-get install clang || die + sudo apt-get install llvm-3.4-runtime || die } [ $BUILD_TARGET != posix -o $CC != clang ] || { diff --git a/.travis/script.sh b/.travis/script.sh index 56a027b9f..05dbc0397 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -70,6 +70,8 @@ set -x } [ $BUILD_TARGET != posix-distcheck ] || { + export ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer-3.4` || die + export ASAN_OPTIONS=symbolize=1 || die BuildJobs=10 make -f examples/Makefile-posix distcheck || die } diff --git a/Makefile.am b/Makefile.am index 7011974b6..286ca918a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am AM_MAKEFLAGS = --no-print-directory AM_DISTCHECK_CONFIGURE_FLAGS = \ + --enable-address-sanitizer \ --enable-cli \ --enable-ncp \ --enable-diag \ diff --git a/configure.ac b/configure.ac index 84138d15e..4a0c6b076 100644 --- a/configure.ac +++ b/configure.ac @@ -283,6 +283,39 @@ NL_ENABLE_OPTIMIZATION([yes]) AM_CONDITIONAL([OPENTHREAD_BUILD_OPTIMIZED], [test "${nl_cv_build_optimized}" = "yes"]) +# Address Sanitizer + +AC_MSG_CHECKING([whether to build with Address Sanitizer support]) +AC_ARG_ENABLE(address-sanitizer, + [AS_HELP_STRING([--enable-address-sanitizer],[Enable Address Sanitizer support @<:@default=no@:>@.])], + [ + case "${enableval}" in + + no|yes) + enable_address_sanitizer=${enableval} + ;; + + *) + AC_MSG_ERROR([Invalid value ${enableval} for --enable-address-sanitizer]) + ;; + + esac + ], + [enable_address_sanitizer=no]) +AC_MSG_RESULT(${enable_address_sanitizer}) + +AM_CONDITIONAL([OPENTHREAD_WITH_ADDRESS_SANITIZER], [test "${enable_address_sanitizer}" = "yes"]) + +if test "${enable_address_sanitizer}" = "yes" ; then + + PROSPECTIVE_CFLAGS="-fsanitize=address" + + # Check if the compilers support address sanitizer + AX_CHECK_COMPILER_OPTIONS([C], ${PROSPECTIVE_CFLAGS}) + AX_CHECK_COMPILER_OPTIONS([C++], ${PROSPECTIVE_CFLAGS}) + +fi + # # Code style # @@ -1039,6 +1072,7 @@ AC_MSG_NOTICE([ Build optimized libraries : ${nl_cv_build_optimized} Build coverage libraries : ${nl_cv_build_coverage} Build coverage reports : ${nl_cv_build_coverage_reports} + Address sanitizer support : ${enable_address_sanitizer} Lcov : ${LCOV:--} Genhtml : ${GENHTML:--} Build tests : ${nl_cv_build_tests} diff --git a/examples/Makefile-posix b/examples/Makefile-posix index c0d9625ba..ebe93cddd 100644 --- a/examples/Makefile-posix +++ b/examples/Makefile-posix @@ -56,8 +56,6 @@ CFLAGS += \ CXXFLAGS += \ $(COMMONCFLAGS) \ - -fno-exceptions \ - -fno-rtti \ $(NULL) LDFLAGS += \ diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 072a7f13f..fadb84164 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -86,23 +86,33 @@ check_PROGRAMS = \ test-toolchain \ $(NULL) +XFAIL_TESTS = \ + $(NULL) + if OPENTHREAD_ENABLE_DIAG -check_PROGRAMS += \ - test-diag \ +check_PROGRAMS += \ + test-diag \ $(NULL) endif if OPENTHREAD_ENABLE_NCP -COMMON_LDADD += \ - $(top_builddir)/src/ncp/libopenthread-ncp.a \ +COMMON_LDADD += \ + $(top_builddir)/src/ncp/libopenthread-ncp.a \ $(NULL) -check_PROGRAMS += \ - test-ncp-buffer \ +check_PROGRAMS += \ + test-ncp-buffer \ $(NULL) + endif # OPENTHREAD_ENABLE_NCP +if OPENTHREAD_WITH_ADDRESS_SANITIZER +check_PROGRAMS += test-address-sanitizer +XFAIL_TESTS += test-address-sanitizer +test_address_sanitizer_SOURCES = test_address_sanitizer.cpp +endif # OPENTHREAD_WITH_ADDRESS_SANITIZER + # Test applications and scripts that should be built and run when the # 'check' target is run. diff --git a/tests/unit/test_address_sanitizer.cpp b/tests/unit/test_address_sanitizer.cpp new file mode 100644 index 000000000..00804ba1c --- /dev/null +++ b/tests/unit/test_address_sanitizer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "test_util.h" + +#ifdef ENABLE_TEST_MAIN +int main(int argc, char *argv[]) +{ + (void)argv; + int stack_array[100]; + int array_index = argc + 100; + + for (int i = 0; i < 100; i++) + { + stack_array[i] = i; + } + + printf("stack_array[%d] = %d\n", array_index, stack_array[array_index]); + + return 0; +} +#endif