diff options
-rw-r--r-- | .ci/clang.sh | 43 | ||||
-rw-r--r-- | .travis.yml | 10 | ||||
-rw-r--r-- | CMakeLists.txt | 20 | ||||
-rw-r--r-- | src/nvim/CMakeLists.txt | 16 | ||||
-rw-r--r-- | src/nvim/spell.c | 2 |
5 files changed, 66 insertions, 25 deletions
diff --git a/.ci/clang.sh b/.ci/clang.sh index b2d9dd3a7a..70ed7d4764 100644 --- a/.ci/clang.sh +++ b/.ci/clang.sh @@ -2,26 +2,36 @@ sudo pip install cpp-coveralls -# Use custom Clang and enable ASAN on Linux. +# Use custom Clang and enable sanitizers on Linux. if [ "$TRAVIS_OS_NAME" = "linux" ]; then - clang_version=3.4.2 - clang_suffix=x86_64-unknown-ubuntu12.04.xz - if [ ! -d /usr/local/clang-$clang_version ]; then - echo "Downloading clang $clang_version..." - sudo mkdir /usr/local/clang-$clang_version - wget -q -O - http://llvm.org/releases/$clang_version/clang+llvm-$clang_version-$clang_suffix \ - | sudo tar xJf - --strip-components=1 -C /usr/local/clang-$clang_version + if [ -z "$CLANG_SANITIZER" ]; then + echo "CLANG_SANITIZER not set." + exit 1 fi - export CC=/usr/local/clang-$clang_version/bin/clang - symbolizer=/usr/local/clang-$clang_version/bin/llvm-symbolizer + + clang_version=3.6 + echo "Installing Clang $clang_version..." + + sudo add-apt-repository "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main" + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA9EF27F + + sudo add-apt-repository "deb http://llvm.org/apt/precise/ llvm-toolchain-precise-$clang_version main" + wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add - + + sudo apt-get update -qq + sudo apt-get install -y -q clang-$clang_version + + export CC=/usr/bin/clang-$clang_version + symbolizer=/usr/bin/llvm-symbolizer-$clang_version export ASAN_SYMBOLIZER_PATH=$symbolizer + export MSAN_SYMBOLIZER_PATH=$symbolizer export ASAN_OPTIONS="detect_leaks=1:log_path=$tmpdir/asan" - export TSAN_OPTIONS="external_symbolizer_path=$symbolizer:log_path=$tmpdir/tsan" + export TSAN_OPTIONS="external_symbolizer_path=$symbolizer log_path=$tmpdir/tsan" export UBSAN_OPTIONS="log_path=$tmpdir/ubsan" # not sure if this works CMAKE_EXTRA_FLAGS="-DTRAVIS_CI_BUILD=ON \ -DUSE_GCOV=ON \ -DBUSTED_OUTPUT_TYPE=plainTerminal \ - -DSANITIZE=ON" + -DCLANG_${CLANG_SANITIZER}=ON" else CMAKE_EXTRA_FLAGS="-DTRAVIS_CI_BUILD=ON \ -DUSE_GCOV=ON \ @@ -38,11 +48,14 @@ build/bin/nvim --version make unittest # Run functional tests. -if ! $MAKE_CMD test; then +# FIXME (fwalch): Disabled for MSAN because of SIGPIPE error. +if [ "$TRAVIS_OS_NAME" = linux ] && ! [ "$CLANG_SANITIZER" = MSAN ]; then + if ! $MAKE_CMD test; then + asan_check "$tmpdir" + exit 1 + fi asan_check "$tmpdir" - exit 1 fi -asan_check "$tmpdir" # Run legacy tests. if ! $MAKE_CMD oldtest; then diff --git a/.travis.yml b/.travis.yml index fb4c69c21b..509b13eec8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,13 +20,19 @@ env: # Force verification of DLOG macros. - CFLAGS='-DMIN_LOG_LEVEL=0' matrix: - - CI_TARGET=clang - CI_TARGET=gcc - CI_TARGET=gcc-32 - CI_TARGET=clint - CI_TARGET=mingw matrix: include: + - os: linux + env: CI_TARGET=clang CLANG_SANITIZER=ASAN_UBSAN + - os: linux + env: CI_TARGET=clang CLANG_SANITIZER=MSAN + # FIXME: Re-enable TSan when tests run successfully. + #- os: linux + # env: CI_TARGET=clang CLANG_SANITIZER=TSAN - os: osx env: CI_TARGET=clang compiler: clang @@ -34,6 +40,8 @@ matrix: env: CI_TARGET=gcc compiler: gcc-4.9 fast_finish: true + allow_failures: + - env: CI_TARGET=clang CLANG_SANITIZER=MSAN before_install: # Pins the version of the java package installed on the Travis VMs # and avoids a lengthy upgrade process for them. diff --git a/CMakeLists.txt b/CMakeLists.txt index 88331490b8..06db4f473e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,13 +191,23 @@ include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS}) find_package(LibVterm REQUIRED) include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS}) -option(SANITIZE "Enable Clang sanitizers for nvim binary" OFF) -if(SANITIZE AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang") - message(WARNING "SANITIZE is only supported for Clang, disabling") - set(SANITIZE OFF) +option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF) +option(CLANG_MSAN "Enable Clang memory sanitizer for nvim binary." OFF) +option(CLANG_TSAN "Enable Clang thread sanitizer for nvim binary." OFF) + +if((CLANG_ASAN_UBSAN AND CLANG_MSAN) + OR (CLANG_ASAN_UBSAN AND CLANG_TSAN) + OR (CLANG_MSAN AND CLANG_TSAN)) + message(FATAL_ERROR "Sanitizers cannot be enabled simultaneously.") endif() -if(NOT SANITIZE) +if((CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang") + message(FATAL_ERROR "Sanitizers are only supported for Clang.") +endif() + +if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) + message(STATUS "Sanitizers have been enabled; don't use jemalloc.") +else() find_package(JeMalloc) if(JEMALLOC_FOUND) include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS}) diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 880ff42ba5..ad5bac1898 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -95,7 +95,7 @@ foreach(gen_cdef ${gen_cdefs} DO_NOT_DEFINE_EMPTY_ATTRIBUTES) list(APPEND gen_cflags "-D${gen_cdef}") endif() endforeach() -if (SANITIZE) +if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) list(APPEND gen_cflags "-DEXITFREE") endif() @@ -190,11 +190,21 @@ add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) -if(SANITIZE) - message(STATUS "Enabling Clang sanitizers for nvim") +if(CLANG_ASAN_UBSAN) + message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.") set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fno-sanitize-recover -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address -fsanitize=undefined ") set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=address -fsanitize=undefined ") +elseif(CLANG_MSAN) + message(STATUS "Enabling Clang memory sanitizer for nvim.") + set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") + set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fno-optimize-sibling-calls ") + set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=memory -fsanitize-memory-track-origins ") +elseif(CLANG_TSAN) + message(STATUS "Enabling Clang thread sanitizer for nvim.") + set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") + set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fsanitize=thread ") + set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=thread ") endif() add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES} diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 63fc7b80a7..f312670a96 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -4116,7 +4116,7 @@ static int badword_captype(char_u *word, char_u *end) // Delete the internal wordlist and its .spl file. void spell_delete_wordlist(void) { - char_u fname[MAXPATHL]; + char_u fname[MAXPATHL] = {0}; if (int_wordlist != NULL) { os_remove((char *)int_wordlist); |