commit
14db9974d4
12 changed files with 118 additions and 67 deletions
16
.github/workflows/code_sanitizers.yml
vendored
16
.github/workflows/code_sanitizers.yml
vendored
|
@ -4,23 +4,29 @@ on: [push, pull_request, workflow_dispatch]
|
|||
|
||||
jobs:
|
||||
linux_sanitizers:
|
||||
name: Linux [${{ matrix.SANITIZER }}] [${{ matrix.BACKEND }} | ${{ matrix.COMPILER }}]
|
||||
name: Linux [${{ matrix.SANITIZER.name }}] [${{ matrix.BACKEND }} | ${{ matrix.COMPILER }}] ${{ matrix.SANITIZER.ignore_errors && ' (Errors Ignored)' || '' }}
|
||||
timeout-minutes: 120
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
BACKEND: [lmdb, rocksdb]
|
||||
COMPILER: [clang]
|
||||
SANITIZER: [ASAN, ASAN_INT, TSAN]
|
||||
SANITIZER:
|
||||
- { name: UBSAN, ignore_errors: false }
|
||||
- { name: ASAN, ignore_errors: true }
|
||||
- { name: ASAN_INT, ignore_errors: true }
|
||||
- { name: TSAN, ignore_errors: true }
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
COMPILER: ${{ matrix.COMPILER }}
|
||||
BACKEND: ${{ matrix.BACKEND }}
|
||||
SANITIZER: ${{ matrix.SANITIZER }}
|
||||
SANITIZER: ${{ matrix.SANITIZER.name }}
|
||||
IGNORE_ERRORS: ${{ matrix.SANITIZER.ignore_errors }}
|
||||
TEST_USE_ROCKSDB: ${{ matrix.BACKEND == 'rocksdb' && '1' || '0' }}
|
||||
DEADLINE_SCALE_FACTOR: ${{ matrix.BACKEND == 'rocksdb' && '2' || '1' }}
|
||||
ASAN_OPTIONS: log_exe_name=1:log_path=sanitizer_report
|
||||
ASAN_OPTIONS: log_exe_name=1:log_path=sanitizer_report:suppressions=../asan_suppressions
|
||||
TSAN_OPTIONS: log_exe_name=1:log_path=sanitizer_report:suppressions=../tsan_suppressions
|
||||
UBSAN_OPTIONS: log_exe_name=1:log_path=sanitizer_report:print_stacktrace=1
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -49,6 +55,6 @@ jobs:
|
|||
|
||||
- name: Reports
|
||||
if: steps.build.outcome == 'success' && (success() || failure())
|
||||
continue-on-error: true
|
||||
continue-on-error: ${{ env.IGNORE_ERRORS == 'true' }}
|
||||
run: ../ci/tests/show-sanitizer-reports.sh
|
||||
working-directory: build
|
||||
|
|
139
CMakeLists.txt
139
CMakeLists.txt
|
@ -146,9 +146,6 @@ if(${NANO_ASIO_HANDLER_TRACKING} GREATER 0)
|
|||
-DBOOST_ASIO_ENABLE_HANDLER_TRACKING)
|
||||
endif()
|
||||
|
||||
option(NANO_ASAN_INT "Enable ASan+UBSan+Integer overflow" OFF)
|
||||
option(NANO_ASAN "Enable ASan+UBSan" OFF)
|
||||
option(NANO_TSAN "Enable TSan" OFF)
|
||||
option(NANO_SIMD_OPTIMIZATIONS
|
||||
"Enable CPU-specific SIMD optimizations (SSE/AVX or NEON, e.g.)" OFF)
|
||||
option(
|
||||
|
@ -216,49 +213,99 @@ endif()
|
|||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(USING_ASAN (NANO_ASAN OR RAIBLOCKS_ASAN))
|
||||
set(USING_ASAN_INT (NANO_ASAN_INT OR RAIBLOCKS_ASAN_INT))
|
||||
set(USING_TSAN (NANO_TSAN OR RAIBLOCKS_TSAN))
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
# Sanitizers
|
||||
option(NANO_ASAN "Enable ASan" OFF)
|
||||
if(NANO_ASAN)
|
||||
if(MSVC)
|
||||
message(FATAL_ERROR "ASan is not supported on MSVC")
|
||||
endif()
|
||||
|
||||
message(STATUS "Using Asan")
|
||||
add_compile_options(-fsanitize=address)
|
||||
add_link_options(-fsanitize=address)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_asan")
|
||||
add_link_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_asan")
|
||||
endif()
|
||||
|
||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
endif()
|
||||
|
||||
option(NANO_ASAN_INT "Enable ASan+Integer overflow" OFF)
|
||||
if(NANO_ASAN_INT)
|
||||
if(MSVC)
|
||||
message(FATAL_ERROR "ASan+Integer overflow is not supported on MSVC")
|
||||
endif()
|
||||
|
||||
message(STATUS "Using ASan+Integer overflow")
|
||||
add_compile_options(-fsanitize=address,integer)
|
||||
add_link_options(-fsanitize=address,integer)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_asan")
|
||||
add_link_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_asan")
|
||||
endif()
|
||||
|
||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
endif()
|
||||
|
||||
option(NANO_UBSAN "Enable UBSan" OFF)
|
||||
if(NANO_UBSAN)
|
||||
if(MSVC)
|
||||
message(FATAL_ERROR "UBSan is not supported on MSVC")
|
||||
endif()
|
||||
|
||||
message(STATUS "Using UBSan")
|
||||
add_compile_options(-fsanitize=undefined)
|
||||
add_link_options(-fsanitize=undefined)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_ubsan")
|
||||
add_link_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_ubsan")
|
||||
endif()
|
||||
|
||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
add_definitions(-DROCKSDB_UBSAN_RUN)
|
||||
endif()
|
||||
|
||||
option(NANO_TSAN "Enable TSan" OFF)
|
||||
if(NANO_TSAN)
|
||||
if(MSVC)
|
||||
message(FATAL_ERROR "TSan is not supported on MSVC")
|
||||
endif()
|
||||
|
||||
message(STATUS "Using TSan")
|
||||
add_compile_options(-fsanitize=thread)
|
||||
add_link_options(-fsanitize=thread)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_tsan")
|
||||
add_link_options(
|
||||
"-fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/sanitize_ignorelist_tsan")
|
||||
endif()
|
||||
|
||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
endif()
|
||||
|
||||
if(NANO_WARN_TO_ERR)
|
||||
add_compile_options(-Werror -Wno-deprecated-declarations)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
find_library(PSAPI Psapi)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600 -DMINIUPNP_STATICLIB
|
||||
-D_CRT_SECURE_NO_WARNINGS -DNOGDI /EHsc)
|
||||
|
||||
if(${USING_TSAN}
|
||||
OR ${USING_ASAN}
|
||||
OR ${USING_ASAN_INT})
|
||||
message(WARNING "Cannot use TSAN or ASAN on Windows, sanitizers ignored")
|
||||
endif()
|
||||
|
||||
else()
|
||||
if(NANO_WARN_TO_ERR)
|
||||
add_compile_options(-Werror -Wno-deprecated-declarations)
|
||||
endif()
|
||||
|
||||
if((${USING_TSAN} AND ${USING_ASAN}) OR (${USING_TSAN} AND ${USING_ASAN_INT}))
|
||||
message(WARNING "Cannot use TSAN/ASAN together, defaulting to ASAN")
|
||||
endif()
|
||||
|
||||
if(${USING_ASAN} OR ${USING_ASAN_INT})
|
||||
if(${USING_ASAN_INT})
|
||||
add_compile_options(-fsanitize=address,undefined,integer)
|
||||
else()
|
||||
add_compile_options(-fsanitize=address,undefined)
|
||||
endif()
|
||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
add_definitions(-DROCKSDB_UBSAN_RUN)
|
||||
elseif(${USING_TSAN})
|
||||
add_compile_options(-fsanitize=thread)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(
|
||||
"-fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tsan_clang_blacklist")
|
||||
endif()
|
||||
add_definitions(-DED25519_NO_INLINE_ASM)
|
||||
endif()
|
||||
|
||||
if(NANO_FUZZER_TEST)
|
||||
add_compile_options(-fsanitize=fuzzer-no-link -fno-omit-frame-pointer)
|
||||
add_definitions(-DNANO_FUZZER_TEST)
|
||||
|
@ -320,20 +367,6 @@ else()
|
|||
set(PLATFORM_LINK_FLAGS "-static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
|
||||
if(${USING_ASAN_INT})
|
||||
set(PLATFORM_LINK_FLAGS
|
||||
"${PLATFORM_LINK_FLAGS} -fsanitize=address,undefined,integer")
|
||||
elseif(${USING_ASAN})
|
||||
set(PLATFORM_LINK_FLAGS
|
||||
"${PLATFORM_LINK_FLAGS} -fsanitize=address,undefined")
|
||||
elseif(${USING_TSAN})
|
||||
set(PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize=thread")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(PLATFORM_LINK_FLAGS
|
||||
"${PLATFORM_LINK_FLAGS} -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/tsan_clang_blacklist"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if(NANO_FUZZER_TEST)
|
||||
set(PLATFORM_LINK_FLAGS "${PLATFORM_LINK_FLAGS} -fsanitize=fuzzer-no-link")
|
||||
endif()
|
||||
|
|
0
asan_suppressions
Normal file
0
asan_suppressions
Normal file
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
set -euox pipefail
|
||||
shopt -s nocasematch # Enable case-insensitive matching
|
||||
|
||||
BUILD_TARGET=""
|
||||
if [[ ${1:-} ]]; then
|
||||
|
@ -35,6 +36,9 @@ if [[ ${SANITIZER:-} ]]; then
|
|||
TSAN)
|
||||
CMAKE_SANITIZER="-DNANO_TSAN=ON"
|
||||
;;
|
||||
UBSAN)
|
||||
CMAKE_SANITIZER="-DNANO_UBSAN=ON"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown sanitizer: '${SANITIZER}'"
|
||||
exit 1
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
set -euox pipefail
|
||||
|
||||
# Clang installer dependencies
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -yqq lsb-release software-properties-common gnupg
|
||||
|
||||
CLANG_VERSION=16
|
||||
|
||||
|
@ -12,4 +15,4 @@ update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-$CLANG_VERSION 10
|
|||
|
||||
# Workaround to get a path that can be easily passed into cmake for BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE
|
||||
# See https://www.boost.org/doc/libs/1_70_0/doc/html/stacktrace/configuration_and_build.html#stacktrace.configuration_and_build.f3
|
||||
backtrace_file=$(find /usr/lib/gcc/ -name 'backtrace.h' | head -n 1) && test -f $backtrace_file && ln -s $backtrace_file /tmp/backtrace.h
|
||||
backtrace_file=$(find /usr/lib/gcc/ -name 'backtrace.h' | head -n 1) && test -f $backtrace_file && ln -s $backtrace_file /tmp/backtrace.h
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
set -euox pipefail
|
|
@ -6,11 +6,12 @@ COMPILER=${COMPILER:-gcc}
|
|||
echo "Compiler: '${COMPILER}'"
|
||||
|
||||
# Common dependencies needed for building & testing
|
||||
apt-get update -qq
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -yqq \
|
||||
build-essential \
|
||||
g++ \
|
||||
curl \
|
||||
wget \
|
||||
python3 \
|
||||
zlib1g-dev \
|
||||
|
|
|
@ -75,7 +75,7 @@ std::shared_ptr<nano::node> nano::test::system::add_node (nano::node_config cons
|
|||
(*j)->network.merge_peer ((*i)->network.endpoint ());
|
||||
|
||||
{
|
||||
auto ec = poll_until_true (3s, [&node1, &node2, starting_size_1, starting_size_2] () {
|
||||
auto ec = poll_until_true (5s, [&node1, &node2, starting_size_1, starting_size_2] () {
|
||||
auto size_1 = node1->network.size ();
|
||||
auto size_2 = node2->network.size ();
|
||||
return size_1 > starting_size_1 && size_2 > starting_size_2;
|
||||
|
@ -87,7 +87,7 @@ std::shared_ptr<nano::node> nano::test::system::add_node (nano::node_config cons
|
|||
{
|
||||
{
|
||||
// Wait for initial connection finish
|
||||
auto ec = poll_until_true (3s, [&node1, &node2, starting_realtime_1, starting_realtime_2] () {
|
||||
auto ec = poll_until_true (5s, [&node1, &node2, starting_realtime_1, starting_realtime_2] () {
|
||||
auto realtime_1 = node1->tcp_listener.realtime_count.load ();
|
||||
auto realtime_2 = node2->tcp_listener.realtime_count.load ();
|
||||
return realtime_1 > starting_realtime_1 && realtime_2 > starting_realtime_2;
|
||||
|
@ -96,7 +96,7 @@ std::shared_ptr<nano::node> nano::test::system::add_node (nano::node_config cons
|
|||
}
|
||||
{
|
||||
// Wait for keepalive message exchange
|
||||
auto ec = poll_until_true (3s, [&node1, &node2, starting_keepalives_1, starting_keepalives_2] () {
|
||||
auto ec = poll_until_true (5s, [&node1, &node2, starting_keepalives_1, starting_keepalives_2] () {
|
||||
auto keepalives_1 = node1->stats.count (stat::type::message, stat::detail::keepalive, stat::dir::in);
|
||||
auto keepalives_2 = node2->stats.count (stat::type::message, stat::detail::keepalive, stat::dir::in);
|
||||
return keepalives_1 > starting_keepalives_1 && keepalives_2 > starting_keepalives_2;
|
||||
|
@ -108,7 +108,7 @@ std::shared_ptr<nano::node> nano::test::system::add_node (nano::node_config cons
|
|||
|
||||
{
|
||||
// Ensure no bootstrap initiators are in progress
|
||||
auto ec = poll_until_true (3s, [this, &begin] () {
|
||||
auto ec = poll_until_true (5s, [this, &begin] () {
|
||||
return std::all_of (begin, nodes.end (), [] (std::shared_ptr<nano::node> const & node_a) { return !node_a->bootstrap_initiator.in_progress (); });
|
||||
});
|
||||
debug_assert (!ec);
|
||||
|
@ -116,7 +116,7 @@ std::shared_ptr<nano::node> nano::test::system::add_node (nano::node_config cons
|
|||
}
|
||||
else
|
||||
{
|
||||
auto ec = poll_until_true (3s, [&node] () {
|
||||
auto ec = poll_until_true (5s, [&node] () {
|
||||
return !node->bootstrap_initiator.in_progress ();
|
||||
});
|
||||
debug_assert (!ec);
|
||||
|
|
4
sanitize_ignorelist
Normal file
4
sanitize_ignorelist
Normal file
|
@ -0,0 +1,4 @@
|
|||
src:*crypto/ed25519*
|
||||
src:*crypto/blake2*
|
||||
|
||||
src:*submodules/lmdb*
|
0
sanitize_ignorelist_asan
Normal file
0
sanitize_ignorelist_asan
Normal file
0
sanitize_ignorelist_tsan
Normal file
0
sanitize_ignorelist_tsan
Normal file
0
sanitize_ignorelist_ubsan
Normal file
0
sanitize_ignorelist_ubsan
Normal file
Loading…
Add table
Add a link
Reference in a new issue