aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2014-03-13 12:11:03 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-03-13 15:26:28 -0300
commitf6ace9962d95eb12236083871154c1501f02c556 (patch)
treef9a1d5b6ca8eaa68114c98dcd92c6161bc15454d
parent3cac32e49c7fae9cf5963d35f3fd3052c061b2fa (diff)
downloadrneovim-f6ace9962d95eb12236083871154c1501f02c556.tar.gz
rneovim-f6ace9962d95eb12236083871154c1501f02c556.tar.bz2
rneovim-f6ace9962d95eb12236083871154c1501f02c556.zip
Refactor travis build to use clang's sanitizers
- Valgrind configuration removed - Fix errors reported by the undefined behavior sanitizer - Travis will now run two build steps: - A normal build of a shared library for unit testing(in parallel with gcc) - A clang build with some sanitizers enabled for integration testing. After these changes travis will run much faster, while providing valgrind-like error detection.
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml7
-rw-r--r--.valgrind.supp7
-rw-r--r--CMakeLists.txt12
-rwxr-xr-xscripts/travis-setup.sh19
-rwxr-xr-xscripts/travis.sh62
-rw-r--r--src/CMakeLists.txt58
-rw-r--r--src/eval.c2
-rw-r--r--src/ex_cmds.c4
9 files changed, 122 insertions, 51 deletions
diff --git a/.gitignore b/.gitignore
index 03ced918a5..e33b0ba01e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
# Build/deps dir
/build/
+/dist/
/.deps/
+/tmp/
*.rej
*.orig
diff --git a/.travis.yml b/.travis.yml
index 2346f865e1..99de0aeaf4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,8 @@
language: c
-script: ./scripts/travis.sh
-before_install:
- - sudo apt-get install valgrind
compiler:
- clang
- gcc
+before_install:
+ - sudo ./scripts/travis-setup.sh
+script:
+ - ./scripts/travis.sh
diff --git a/.valgrind.supp b/.valgrind.supp
deleted file mode 100644
index a0a96518ba..0000000000
--- a/.valgrind.supp
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- nss_parse_service_list
- Memcheck:Leak
- fun:malloc
- fun:nss_parse_service_list
- fun:__nss_database_lookup
-}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c2a2b71915..c5b59ce403 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,12 +10,7 @@ set(NEOVIM_VERSION_PATCH 0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-# If the C compiler is some GNU-alike, use the gnu99 standard and enable all warnings.
-if(CMAKE_COMPILER_IS_GNUCC)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -Wextra -pedantic -Wno-unused-parameter -std=gnu99")
-elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -Wextra -pedantic -Wno-unused-parameter -std=gnu99")
-endif(CMAKE_COMPILER_IS_GNUCC)
+add_definitions(-Werror -Wall -Wextra -pedantic -Wno-unused-parameter -std=gnu99)
add_definitions(-DHAVE_CONFIG_H)
if(CMAKE_BUILD_TYPE MATCHES Debug)
@@ -25,11 +20,6 @@ else()
set(DEBUG 0)
endif()
-if(DEFINED ENV{VALGRIND_CHECK})
- message(STATUS "Defining EXITFREE for valgrind checks")
- add_definitions(-DEXITFREE)
-endif()
-
# Modules used by platform auto-detection
include(CheckLibraryExists)
diff --git a/scripts/travis-setup.sh b/scripts/travis-setup.sh
new file mode 100755
index 0000000000..437659dd77
--- /dev/null
+++ b/scripts/travis-setup.sh
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+
+# [ "$CC" != "clang" ] && exit
+
+add-apt-repository -y ppa:ubuntu-toolchain-r/ppa
+wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add -
+
+cat > /etc/apt/sources.list.d/clang.list << "EOF"
+deb http://llvm.org/apt/precise/ llvm-toolchain-precise main
+deb-src http://llvm.org/apt/precise/ llvm-toolchain-precise main
+# 3.4
+deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.4 main
+deb-src http://llvm.org/apt/precise/ llvm-toolchain-precise-3.4 main
+# Common
+deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main
+EOF
+
+apt-get -qq update
+apt-get -qq -y --no-install-recommends install clang-3.4 lldb-3.4
diff --git a/scripts/travis.sh b/scripts/travis.sh
index 7292953710..fb5a770863 100755
--- a/scripts/travis.sh
+++ b/scripts/travis.sh
@@ -1,21 +1,49 @@
#!/bin/sh -e
-export VALGRIND_CHECK=1
-export BUSTED_OUTPUT_TYPE="TAP"
-make cmake CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$PWD/dist"
-make
-make unittest
-echo "Running tests with valgrind..."
-if ! make test; then
- if ls src/testdir/valgrind.* > /dev/null 2>&1; then
- echo "Memory leak detected" >&2
- cat src/testdir/valgrind.*
- else
- echo "Failed tests:" >&2
- for t in src/testdir/*.failed; do
- echo ${t%%.*}
- done
+check_and_report() {
+ reset
+ (
+ cd $tmpdir
+ if [ -f asan.* ] || [ -f tsan.* ] || [ -f ubsan.* ]; then
+ cat $tmpdir/asan.* 2> /dev/null || true
+ cat $tmpdir/tsan.* 2> /dev/null || true
+ cat $tmpdir/ubsan.* 2> /dev/null || true
+ exit 1
fi
- exit 1
+ )
+}
+
+if [ "$CC" = "clang" ]; then
+ # force using the version installed by 'travis-setup.sh'
+ export CC=/usr/bin/clang
+
+ install_dir="$(pwd)/dist"
+ # temporary directory for writing sanitizer logs
+ tmpdir="$(pwd)/tmp"
+ rm -rf "$tmpdir"
+ mkdir -p "$tmpdir"
+
+ # need the symbolizer path for stack traces with source information
+ symbolizer=/usr/bin/llvm-symbolizer-3.4
+
+ export SKIP_UNITTEST=1
+ export SANITIZE=1
+ export ASAN_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 UBSAN_OPTIONS="log_path=$tmpdir/ubsan" # not sure if this works
+
+ make cmake CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$install_dir"
+ make
+ if ! make test; then
+ check_and_report
+ fi
+ check_and_report
+ make install
+else
+ export BUSTED_OUTPUT_TYPE="TAP"
+ export SKIP_EXEC=1
+ make cmake
+ make unittest
fi
-make install
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 359a9f5180..fecfea8cdf 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,8 +12,25 @@ list(APPEND NEOVIM_SOURCES "${PROJECT_BINARY_DIR}/config/auto/pathdef.c")
file( GLOB OS_SOURCES os/*.c )
-add_executable (nvim ${NEOVIM_SOURCES} ${OS_SOURCES})
-add_library (nvim-test MODULE ${NEOVIM_SOURCES} ${OS_SOURCES})
+if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(DEFINED ENV{SANITIZE})
+ message(STATUS "Enabling the sanitizers")
+ add_definitions(-DEXITFREE) # is this necessary for LeakSanitizer?
+ add_definitions(-fno-sanitize-recover -fno-omit-frame-pointer
+ -fno-optimize-sibling-calls -fsanitize=address -fsanitize=undefined)
+ set(CMAKE_EXE_LINKER_FLAGS
+ "-fsanitize=address -fsanitize=undefined ${CMAKE_EXE_LINKER_FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS
+ "-fsanitize=address -fsanitize=undefined ${CMAKE_SHARED_LINKER_FLAGS}")
+ endif()
+endif()
+
+if(NOT DEFINED ENV{SKIP_EXEC})
+ add_executable (nvim ${NEOVIM_SOURCES} ${OS_SOURCES})
+endif()
+if(NOT DEFINED ENV{SKIP_UNITTEST})
+ add_library (nvim-test MODULE ${NEOVIM_SOURCES} ${OS_SOURCES})
+endif()
# The libraries we link against for nvim
set(NVIM_LINK_LIBRARIES m ${LibUV_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
@@ -28,27 +45,46 @@ if (LibIntl_FOUND)
list(APPEND NVIM_LINK_LIBRARIES ${LibIntl_LIBRARY})
endif()
-target_link_libraries (nvim ${NVIM_LINK_LIBRARIES})
-target_link_libraries (nvim-test ${NVIM_LINK_LIBRARIES})
+if(NOT DEFINED ENV{SKIP_EXEC})
+ target_link_libraries (nvim ${NVIM_LINK_LIBRARIES})
+endif()
+if(NOT DEFINED ENV{SKIP_UNITTEST})
+ target_link_libraries (nvim-test ${NVIM_LINK_LIBRARIES})
+endif()
include(CheckLibraryExists)
check_library_exists(termcap tgetent "" HAVE_LIBTERMCAP)
if (HAVE_LIBTERMCAP)
- target_link_libraries(nvim termcap)
- target_link_libraries(nvim-test termcap)
+
+ if(NOT DEFINED ENV{SKIP_EXEC})
+ target_link_libraries(nvim termcap)
+ endif()
+ if(NOT DEFINED ENV{SKIP_UNITTEST})
+ target_link_libraries(nvim-test termcap)
+ endif()
else()
check_library_exists(curses tgetent "" HAVE_LIBCURSES)
if (HAVE_LIBCURSES)
- target_link_libraries(nvim curses)
- target_link_libraries(nvim-test curses)
+ if(NOT DEFINED ENV{SKIP_EXEC})
+ target_link_libraries(nvim curses)
+ endif()
+ if(NOT DEFINED ENV{SKIP_UNITTEST})
+ target_link_libraries(nvim-test curses)
+ endif()
else()
find_package(Curses REQUIRED)
- target_link_libraries(nvim ${CURSES_LIBRARIES})
- target_link_libraries(nvim-test ${CURSES_LIBRARIES})
+ if(NOT DEFINED ENV{SKIP_EXEC})
+ target_link_libraries(nvim ${CURSES_LIBRARIES})
+ endif()
+ if(DEFINED ENV{SKIP_UNITTEST})
+ target_link_libraries(nvim-test ${CURSES_LIBRARIES})
+ endif()
endif()
endif()
include_directories ("${PROJECT_SOURCE_DIR}/src/proto")
-install(TARGETS nvim RUNTIME DESTINATION bin)
+if(NOT DEFINED ENV{SKIP_EXEC})
+ install(TARGETS nvim RUNTIME DESTINATION bin)
+endif()
diff --git a/src/eval.c b/src/eval.c
index b164912c1c..d5ed1b1e04 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4275,7 +4275,7 @@ eval6 (
else if (op == '/') {
/* We rely on the floating point library to handle divide
* by zero to result in "inf" and not a crash. */
- f1 = f1 / f2;
+ f1 = f2 != 0 ? f1 / f2 : INFINITY;
} else {
EMSG(_("E804: Cannot use '%' with Float"));
return FAIL;
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 68b5727786..c4da8d65e7 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2834,8 +2834,10 @@ do_ecmd (
* <VN> We could instead free the synblock
* and re-attach to buffer, perhaps.
*/
- if (curwin->w_s == &(curwin->w_buffer->b_s))
+ if (curwin->w_buffer != NULL &&
+ curwin->w_s == &(curwin->w_buffer->b_s))
curwin->w_s = &(buf->b_s);
+
curwin->w_buffer = buf;
curbuf = buf;
++curbuf->b_nwindows;