mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-22 04:55:48 +03:00
Add CMake option to enable address sanitizers
Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
This commit is contained in:
parent
31179131f2
commit
e2d0481c64
6 changed files with 205 additions and 41 deletions
|
@ -9,7 +9,7 @@ steps:
|
||||||
path: /drone/build
|
path: /drone/build
|
||||||
commands:
|
commands:
|
||||||
- cd /drone/build
|
- cd /drone/build
|
||||||
- cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DSANITIZE_ADDRESS=ON ../src
|
- cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address ../src
|
||||||
- name: compile
|
- name: compile
|
||||||
image: nextcloudci/client-5.12:client-5.12-11
|
image: nextcloudci/client-5.12:client-5.12-11
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -53,7 +53,7 @@ steps:
|
||||||
path: /drone/build
|
path: /drone/build
|
||||||
commands:
|
commands:
|
||||||
- cd /drone/build
|
- cd /drone/build
|
||||||
- cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DSANITIZE_ADDRESS=ON ../src
|
- cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address ../src
|
||||||
- name: compile
|
- name: compile
|
||||||
image: nextcloudci/client-5.12:client-5.12-11
|
image: nextcloudci/client-5.12:client-5.12-11
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
@ -233,8 +233,6 @@ if (APPLE)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(SanitizerFlags)
|
|
||||||
|
|
||||||
# Handle Translations, pick all client_* files from trans directory.
|
# Handle Translations, pick all client_* files from trans directory.
|
||||||
file( GLOB TRANS_FILES ${CMAKE_SOURCE_DIR}/translations/client_*.ts)
|
file( GLOB TRANS_FILES ${CMAKE_SOURCE_DIR}/translations/client_*.ts)
|
||||||
set(TRANSLATIONS ${TRANS_FILES})
|
set(TRANSLATIONS ${TRANS_FILES})
|
||||||
|
|
169
cmake/modules/ECMEnableSanitizers.cmake
Normal file
169
cmake/modules/ECMEnableSanitizers.cmake
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
# SPDX-FileCopyrightText: 2014 Mathieu Tarral <mathieu.tarral@gmail.com>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
#[=======================================================================[.rst:
|
||||||
|
ECMEnableSanitizers
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Enable compiler sanitizer flags.
|
||||||
|
|
||||||
|
The following sanitizers are supported:
|
||||||
|
|
||||||
|
- Address Sanitizer
|
||||||
|
- Memory Sanitizer
|
||||||
|
- Thread Sanitizer
|
||||||
|
- Leak Sanitizer
|
||||||
|
- Undefined Behaviour Sanitizer
|
||||||
|
|
||||||
|
All of them are implemented in Clang, depending on your version, and
|
||||||
|
there is an work in progress in GCC, where some of them are currently
|
||||||
|
implemented.
|
||||||
|
|
||||||
|
This module will check your current compiler version to see if it
|
||||||
|
supports the sanitizers that you want to enable
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
Simply add::
|
||||||
|
|
||||||
|
include(ECMEnableSanitizers)
|
||||||
|
|
||||||
|
to your ``CMakeLists.txt``. Note that this module is included in
|
||||||
|
KDECompilerSettings, so projects using that module do not need to also
|
||||||
|
include this one.
|
||||||
|
|
||||||
|
The sanitizers are not enabled by default. Instead, you must set
|
||||||
|
``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the
|
||||||
|
command line) to a semicolon-separated list of sanitizers you wish to enable.
|
||||||
|
The options are:
|
||||||
|
|
||||||
|
- address
|
||||||
|
- memory
|
||||||
|
- thread
|
||||||
|
- leak
|
||||||
|
- undefined
|
||||||
|
- fuzzer
|
||||||
|
|
||||||
|
The sanitizers "address", "memory" and "thread" are mutually exclusive. You
|
||||||
|
cannot enable two of them in the same build.
|
||||||
|
|
||||||
|
"leak" requires the "address" sanitizer.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
To reduce the overhead induced by the instrumentation of the sanitizers, it
|
||||||
|
is advised to enable compiler optimizations (``-O1`` or higher).
|
||||||
|
|
||||||
|
Example
|
||||||
|
=======
|
||||||
|
|
||||||
|
This is an example of usage::
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' ..
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Most of the sanitizers will require Clang. To enable it, use::
|
||||||
|
|
||||||
|
-DCMAKE_CXX_COMPILER=clang++
|
||||||
|
|
||||||
|
Since 1.3.0.
|
||||||
|
#]=======================================================================]
|
||||||
|
|
||||||
|
# MACRO check_compiler_version
|
||||||
|
#-----------------------------
|
||||||
|
macro (check_compiler_version gcc_required_version clang_required_version msvc_required_version)
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
CMAKE_CXX_COMPILER_ID MATCHES "GNU"
|
||||||
|
AND
|
||||||
|
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${gcc_required_version}
|
||||||
|
)
|
||||||
|
OR
|
||||||
|
(
|
||||||
|
CMAKE_CXX_COMPILER_ID MATCHES "Clang"
|
||||||
|
AND
|
||||||
|
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${clang_required_version}
|
||||||
|
)
|
||||||
|
OR
|
||||||
|
(
|
||||||
|
CMAKE_CXX_COMPILER_ID MATCHES "MSVC"
|
||||||
|
AND
|
||||||
|
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${msvc_required_version}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# error !
|
||||||
|
message(FATAL_ERROR "You ask to enable the sanitizer ${CUR_SANITIZER},
|
||||||
|
but your compiler ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}
|
||||||
|
does not support it !
|
||||||
|
You should use at least GCC ${gcc_required_version}, Clang ${clang_required_version}
|
||||||
|
or MSVC ${msvc_required_version}
|
||||||
|
(99.99 means not implemented yet)")
|
||||||
|
endif ()
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
# MACRO check_compiler_support
|
||||||
|
#------------------------------
|
||||||
|
macro (enable_sanitizer_flags sanitize_option)
|
||||||
|
if (${sanitize_option} MATCHES "address")
|
||||||
|
check_compiler_version("4.8" "3.1" "19.28")
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=address")
|
||||||
|
else()
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||||
|
set(XSAN_LINKER_FLAGS "-fsanitize=address")
|
||||||
|
endif()
|
||||||
|
elseif (${sanitize_option} MATCHES "thread")
|
||||||
|
check_compiler_version("4.8" "3.1" "99.99")
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
|
||||||
|
set(XSAN_LINKER_FLAGS "tsan")
|
||||||
|
elseif (${sanitize_option} MATCHES "memory")
|
||||||
|
check_compiler_version("99.99" "3.1" "99.99")
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=memory")
|
||||||
|
elseif (${sanitize_option} MATCHES "leak")
|
||||||
|
check_compiler_version("4.9" "3.4" "99.99")
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=leak")
|
||||||
|
set(XSAN_LINKER_FLAGS "lsan")
|
||||||
|
elseif (${sanitize_option} MATCHES "undefined")
|
||||||
|
check_compiler_version("4.9" "3.1" "99.99")
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||||
|
elseif (${sanitize_option} MATCHES "fuzzer")
|
||||||
|
check_compiler_version("99.99" "6.0" "99.99")
|
||||||
|
set(XSAN_COMPILE_FLAGS "-fsanitize=fuzzer")
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.")
|
||||||
|
endif ()
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
if (ECM_ENABLE_SANITIZERS)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
|
# for each element of the ECM_ENABLE_SANITIZERS list
|
||||||
|
foreach ( CUR_SANITIZER ${ECM_ENABLE_SANITIZERS} )
|
||||||
|
# lowercase filter
|
||||||
|
string(TOLOWER ${CUR_SANITIZER} CUR_SANITIZER)
|
||||||
|
# check option and enable appropriate flags
|
||||||
|
enable_sanitizer_flags ( ${CUR_SANITIZER} )
|
||||||
|
# TODO: GCC will not link pthread library if enabled ASan
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${XSAN_COMPILE_FLAGS}" )
|
||||||
|
link_libraries(${XSAN_LINKER_FLAGS})
|
||||||
|
endif()
|
||||||
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XSAN_COMPILE_FLAGS}" )
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
|
link_libraries(${XSAN_LINKER_FLAGS})
|
||||||
|
endif()
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
string(REPLACE "-Wl,--no-undefined" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||||
|
string(REPLACE "-Wl,--no-undefined" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
|
||||||
|
link_libraries(${XSAN_LINKER_FLAGS})
|
||||||
|
endif ()
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
message(STATUS "Tried to enable sanitizers (-DECM_ENABLE_SANITIZERS=${ECM_ENABLE_SANITIZERS}), \
|
||||||
|
but compiler (${CMAKE_CXX_COMPILER_ID}) does not have sanitizer support")
|
||||||
|
endif()
|
||||||
|
endif()
|
|
@ -1,37 +0,0 @@
|
||||||
# Enable address sanitizer (gcc/clang only)
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
|
||||||
set(SANITIZERS)
|
|
||||||
set(SANITIZER_EXTRA_FLAGS " -g")
|
|
||||||
|
|
||||||
macro(add_sanitizer_option variable flag help)
|
|
||||||
option(${variable} "Enable ${help}" OFF)
|
|
||||||
if(${variable})
|
|
||||||
list(APPEND SANITIZERS ${flag})
|
|
||||||
string(REPLACE ";" " " optional_args "${ARGN}")
|
|
||||||
if(optional_args)
|
|
||||||
string(APPEND SANITIZER_EXTRA_FLAGS " ${optional_args}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
mark_as_advanced(${variable})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
add_sanitizer_option(SANITIZE_ADDRESS "address"
|
|
||||||
"AddressSanitizer (detects memory violations, buffer overflows, memory leaks)")
|
|
||||||
add_sanitizer_option(SANITIZE_LEAK "leak"
|
|
||||||
"standalone LeakSanitizer (detects memory leaks only)")
|
|
||||||
add_sanitizer_option(SANITIZE_MEMORY "memory"
|
|
||||||
"MemorySanitizer (detects reads in uninitialized memory)")
|
|
||||||
add_sanitizer_option(SANITIZE_UNDEFINED "undefined"
|
|
||||||
"UndefinedBehaviorSanitizer (detects undefined behavior)"
|
|
||||||
"-fno-sanitize=vptr")
|
|
||||||
add_sanitizer_option(SANITIZE_THREAD "thread"
|
|
||||||
"ThreadSanitizer (detects data races)")
|
|
||||||
|
|
||||||
if(SANITIZERS)
|
|
||||||
string(REPLACE ";" "," SANITIZER_FLAGS "${SANITIZERS}")
|
|
||||||
set(SANITIZER_FLAGS "-fsanitize=${SANITIZER_FLAGS}${SANITIZER_EXTRA_FLAGS}")
|
|
||||||
string(APPEND CMAKE_CXX_FLAGS " ${SANITIZER_FLAGS}")
|
|
||||||
string(APPEND CMAKE_C_FLAGS " ${SANITIZER_FLAGS}")
|
|
||||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${SANITIZER_FLAGS}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
|
@ -373,6 +373,38 @@ The following are known cmake parameters:
|
||||||
* ``BUILD_WITH_QT4=ON``: Builds using Qt4 (even if Qt5 is found).
|
* ``BUILD_WITH_QT4=ON``: Builds using Qt4 (even if Qt5 is found).
|
||||||
* ``CMAKE_INSTALL_PREFIX=path``: Set an install prefix. This is mandatory on Mac OS
|
* ``CMAKE_INSTALL_PREFIX=path``: Set an install prefix. This is mandatory on Mac OS
|
||||||
|
|
||||||
|
Address Sanitizer
|
||||||
|
=================
|
||||||
|
|
||||||
|
You can enable the address sanitizer to detect memory corruptions and other mistakes.
|
||||||
|
The are the following sanitizers are available:
|
||||||
|
|
||||||
|
|
||||||
|
* Address Sanitizer
|
||||||
|
* Leak anitizer
|
||||||
|
* Memory sanitizer
|
||||||
|
* Undefined sanitizer
|
||||||
|
* Threads sanitizer
|
||||||
|
|
||||||
|
You can enable one or more sanitizers through CMake. For example, to
|
||||||
|
enable the address and the undefined sanitizer, execute CMake like
|
||||||
|
``cmake .. -D ECM_ENABLE_SANITIZERS="address;undefined"``.
|
||||||
|
Keep in mind that not all combinations of sanitizers work together, and on some
|
||||||
|
platforms, not all types of sanitizers are available. For example, on Windows there is
|
||||||
|
currently only the address sanitizer available. If you are on Windows, you need to
|
||||||
|
make sure that the linker can find the sanitizer dlls at runtime. If you installed
|
||||||
|
Visual Studio in the standard location, you could find them in
|
||||||
|
**C:/ProgramFiles (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/lib/clang/10.0.0/lib/windows**.
|
||||||
|
Make sure you add this location to your path. You may also need to
|
||||||
|
`upgrade your Visual Studio version <https://docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-160#install-the-addresssanitizer>`_.
|
||||||
|
|
||||||
|
.. note:: If you use Visual Studio on Windows, you can enable the
|
||||||
|
sanitizer if you click on **Manage Configurations**, scroll
|
||||||
|
down to the section **CMake Command Arguments** and enter then
|
||||||
|
``-D ECM_ENABLE_SANITIZERS="address"`` in the text input field below.
|
||||||
|
After that, click on **Save and generate CMake cache to load variables**
|
||||||
|
right above the table.
|
||||||
|
|
||||||
.. _CMake: http://www.cmake.org/download
|
.. _CMake: http://www.cmake.org/download
|
||||||
.. _CSync: http://www.csync.org
|
.. _CSync: http://www.csync.org
|
||||||
.. _Client Download Page: https://nextcloud.com/install/#install-clients
|
.. _Client Download Page: https://nextcloud.com/install/#install-clients
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
if(NOT TOKEN_AUTH_ONLY)
|
if(NOT TOKEN_AUTH_ONLY)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(ECMEnableSanitizers)
|
||||||
|
|
||||||
set(synclib_NAME ${APPLICATION_EXECUTABLE}sync)
|
set(synclib_NAME ${APPLICATION_EXECUTABLE}sync)
|
||||||
|
|
||||||
find_package(Qt5 5.12 COMPONENTS Core Network Xml Concurrent WebEngineWidgets WebEngine REQUIRED)
|
find_package(Qt5 5.12 COMPONENTS Core Network Xml Concurrent WebEngineWidgets WebEngine REQUIRED)
|
||||||
|
|
Loading…
Reference in a new issue