From b4e1a417be94998965986682be30bf3959324f10 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Sat, 13 May 2023 15:22:47 +0000 Subject: [PATCH 1/6] contrib: add LLVM/Clang 15 to CI container --- contrib/containers/ci/Dockerfile | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/contrib/containers/ci/Dockerfile b/contrib/containers/ci/Dockerfile index 7fe1a72feeba..b74b9466a97f 100644 --- a/contrib/containers/ci/Dockerfile +++ b/contrib/containers/ci/Dockerfile @@ -77,8 +77,7 @@ RUN apt-get update && apt-get install $APT_ARGS \ wine-stable \ wine32 \ wine64 \ - xorriso \ - && rm -rf /var/lib/apt/lists/* + xorriso ARG CPPCHECK_VERSION=2.10 RUN curl -sL "https://github.com/danmar/cppcheck/archive/${CPPCHECK_VERSION}.tar.gz" | tar -xvzf - --directory /tmp/ @@ -102,6 +101,20 @@ RUN \ update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; \ exit 0 +ARG LLVM_VERSION=15 +# Setup Clang+LLVM support +RUN apt-get update && apt-get install $APT_ARGS \ + lsb-release \ + software-properties-common \ + gnupg \ + && rm -rf /var/lib/apt/lists/* + +RUN cd /tmp && \ + wget https://apt.llvm.org/llvm.sh && \ + chmod +x llvm.sh && \ + /tmp/llvm.sh ${LLVM_VERSION} && \ + rm -rf /tmp/llvm.sh + RUN \ mkdir -p /src/dash && \ mkdir -p /cache/ccache && \ From 82cc03dddd45a7401c0bc5f334d40633447183e7 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Wed, 17 May 2023 06:59:56 +0000 Subject: [PATCH 2/6] ci: build TSan with clang 15 and add -Werror=thread-safety --- ci/test/00_setup_env_native_tsan.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index a34a22609673..633f54bdfb81 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -12,5 +12,6 @@ export DEP_OPTS="NO_UPNP=1 DEBUG=1" export TEST_RUNNER_EXTRA="--extended --exclude feature_pruning,feature_dbcrash,wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163) export GOAL="install" export BITCOIN_CONFIG="--enable-zmq --enable-reduce-exports --enable-crash-hooks --with-sanitizers=thread" +export BITCOIN_CONFIG="${BITCOIN_CONFIG} CC=clang-15 CXX=clang++-15 CXXFLAGS=-Werror=thread-safety" export CPPFLAGS="-DDEBUG_LOCKORDER -DENABLE_DASH_DEBUG -DARENA_DEBUG" export PYZMQ=true From 0c9d80628683d1a1cdfd23f815dfe179074b0add Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Thu, 25 May 2023 07:54:37 +0000 Subject: [PATCH 3/6] ci: add --enable-suppress-external-warning to TSan CI flags Clang's warnings are far noisier and warnings about deprecations and the like from our dependencies are out of our control (and with dependencies like Boost, clog up the build log to the point GitLab stops logging) --- ci/test/00_setup_env_native_tsan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 633f54bdfb81..55bffa86e612 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -11,7 +11,7 @@ export PACKAGES="clang-8 llvm-8 python3-zmq qtbase5-dev qttools5-dev-tools libev export DEP_OPTS="NO_UPNP=1 DEBUG=1" export TEST_RUNNER_EXTRA="--extended --exclude feature_pruning,feature_dbcrash,wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163) export GOAL="install" -export BITCOIN_CONFIG="--enable-zmq --enable-reduce-exports --enable-crash-hooks --with-sanitizers=thread" +export BITCOIN_CONFIG="--enable-zmq --enable-reduce-exports --enable-crash-hooks --enable-suppress-external-warnings --with-sanitizers=thread" export BITCOIN_CONFIG="${BITCOIN_CONFIG} CC=clang-15 CXX=clang++-15 CXXFLAGS=-Werror=thread-safety" export CPPFLAGS="-DDEBUG_LOCKORDER -DENABLE_DASH_DEBUG -DARENA_DEBUG" export PYZMQ=true From cf444fe96f0bcdfb739000792ef289c424e92b6e Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Thu, 25 May 2023 08:15:55 +0000 Subject: [PATCH 4/6] ci: use wrapped functions when building with clang --- src/stacktraces.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/stacktraces.cpp b/src/stacktraces.cpp index 23f76f27e420..d59dd74a4ff7 100644 --- a/src/stacktraces.cpp +++ b/src/stacktraces.cpp @@ -536,12 +536,9 @@ static std::map>> g_stacktraces; #if CRASH_HOOKS_WRAPPED_CXX_ABI // These come in through -Wl,-wrap -// It only works on GCC extern "C" void* __real___cxa_allocate_exception(size_t thrown_size); extern "C" void __real___cxa_free_exception(void * thrown_exception); -#if __clang__ -#error not supported on WIN32 (no dlsym support) -#elif WIN32 +#if WIN32 extern "C" void __real__assert(const char *assertion, const char *file, unsigned int line); extern "C" void __real__wassert(const wchar_t *assertion, const wchar_t *file, unsigned int line); #else From 97b181bf822693f774ef44926e779bbf3b3fd6d3 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Fri, 19 May 2023 05:55:22 +0000 Subject: [PATCH 5/6] fix: use check for definition instead of definition and its value `#elifdef` is introduced since C++23 but we target at most, C++17 and since a lot of conditional logic relies on else statements that should only check for presence rather than evaluate its value, it's better to consistently use `#if defined(__MACRO__)` instead of `#ifdef __MACRO__` for checking platform flags until the time we bump to C++23 --- src/stacktraces.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/stacktraces.cpp b/src/stacktraces.cpp index d59dd74a4ff7..59a096158513 100644 --- a/src/stacktraces.cpp +++ b/src/stacktraces.cpp @@ -18,7 +18,7 @@ #include #include -#if WIN32 +#if defined(WIN32) #include #include #include @@ -30,14 +30,14 @@ #include #endif -#if !WIN32 +#if !defined(WIN32) #include -#if !__APPLE__ +#if !defined(__APPLE__) #include #endif #endif -#if __APPLE__ +#if defined(__APPLE__) #include #include #include @@ -52,7 +52,7 @@ std::string DemangleSymbol(const std::string& name) { -#if __GNUC__ || __clang__ +#if defined(__GNUC__) || defined(__clang__) int status = -4; // some arbitrary value to eliminate the compiler warning char* str = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status); if (status != 0) { @@ -74,7 +74,7 @@ static std::atomic skipAbortSignal(false); static ssize_t GetExeFileNameImpl(char* buf, size_t bufSize) { -#if WIN32 +#if defined(WIN32) std::vector tmp(bufSize); DWORD len = GetModuleFileName(nullptr, tmp.data(), bufSize); if (len >= bufSize) { @@ -84,7 +84,7 @@ static ssize_t GetExeFileNameImpl(char* buf, size_t bufSize) buf[i] = (char)tmp[i]; } return len; -#elif __APPLE__ +#elif defined(__APPLE__) uint32_t bufSize2 = (uint32_t)bufSize; if (_NSGetExecutablePath(buf, &bufSize2) != 0) { // it's not entirely clear if the value returned by _NSGetExecutablePath includes the null character @@ -127,7 +127,7 @@ static void my_backtrace_error_callback (void *data, const char *msg, static backtrace_state* GetLibBacktraceState() { -#if WIN32 +#if defined(WIN32) // libbacktrace is not able to handle the DWARF debuglink in the .exe // but luckily we can just specify the .dbg file here as it's a valid PE/XCOFF file static std::string debugFileName = g_exeFileName + ".dbg"; @@ -140,7 +140,7 @@ static backtrace_state* GetLibBacktraceState() } #endif // ENABLE_STACKTRACES -#if WIN32 +#if defined(WIN32) static uint64_t GetBaseAddress() { return 0; @@ -188,7 +188,7 @@ static __attribute__((noinline)) std::vector GetStackFrames(size_t ski STACKFRAME64 stackframe; ZeroMemory(&stackframe, sizeof(STACKFRAME64)); -#ifdef __i386__ +#if defined(__i386__) image = IMAGE_FILE_MACHINE_I386; stackframe.AddrPC.Offset = context.Eip; stackframe.AddrPC.Mode = AddrModeFlat; @@ -196,7 +196,7 @@ static __attribute__((noinline)) std::vector GetStackFrames(size_t ski stackframe.AddrFrame.Mode = AddrModeFlat; stackframe.AddrStack.Offset = context.Esp; stackframe.AddrStack.Mode = AddrModeFlat; -#elif __x86_64__ +#elif defined(__x86_64__) image = IMAGE_FILE_MACHINE_AMD64; stackframe.AddrPC.Offset = context.Rip; stackframe.AddrPC.Mode = AddrModeFlat; @@ -240,7 +240,7 @@ static __attribute__((noinline)) std::vector GetStackFrames(size_t ski } #else -#if __APPLE__ +#if defined(__APPLE__) static uint64_t GetBaseAddress() { mach_port_name_t target_task; @@ -534,11 +534,11 @@ static void PrintCrashInfo(const crash_info& ci) static StdMutex g_stacktraces_mutex; static std::map>> g_stacktraces; -#if CRASH_HOOKS_WRAPPED_CXX_ABI +#ifdef CRASH_HOOKS_WRAPPED_CXX_ABI // These come in through -Wl,-wrap extern "C" void* __real___cxa_allocate_exception(size_t thrown_size); extern "C" void __real___cxa_free_exception(void * thrown_exception); -#if WIN32 +#if defined(WIN32) extern "C" void __real__assert(const char *assertion, const char *file, unsigned int line); extern "C" void __real__wassert(const wchar_t *assertion, const wchar_t *file, unsigned int line); #else @@ -557,13 +557,13 @@ extern "C" void __real___cxa_free_exception(void * thrown_exception) static auto f = (void(*)(void*))dlsym(RTLD_NEXT, "__cxa_free_exception"); return f(thrown_exception); } -#if __clang__ +#if defined(__clang__) extern "C" void __attribute__((noreturn)) __real___assert_rtn(const char *function, const char *file, int line, const char *assertion) { static auto f = (void(__attribute__((noreturn)) *) (const char*, const char*, int, const char*))dlsym(RTLD_NEXT, "__assert_rtn"); f(function, file, line, assertion); } -#elif WIN32 +#elif defined(WIN32) #error not supported on WIN32 (no dlsym support) #else extern "C" void __real___assert_fail(const char *assertion, const char *file, unsigned int line, const char *function) @@ -574,7 +574,7 @@ extern "C" void __real___assert_fail(const char *assertion, const char *file, un #endif #endif -#if CRASH_HOOKS_WRAPPED_CXX_ABI +#ifdef CRASH_HOOKS_WRAPPED_CXX_ABI #define WRAPPED_NAME(x) __wrap_##x #else #define WRAPPED_NAME(x) x @@ -622,7 +622,7 @@ static __attribute__((noinline)) crash_info GetCrashInfoFromAssertion(const char return ci; } -#if __clang__ +#if defined(__clang__) extern "C" void __attribute__((noinline)) WRAPPED_NAME(__assert_rtn)(const char *function, const char *file, int line, const char *assertion) { auto ci = GetCrashInfoFromAssertion(assertion, file, line, function); @@ -630,7 +630,7 @@ extern "C" void __attribute__((noinline)) WRAPPED_NAME(__assert_rtn)(const char skipAbortSignal = true; __real___assert_rtn(function, file, line, assertion); } -#elif WIN32 +#elif defined(WIN32) extern "C" void __attribute__((noinline)) WRAPPED_NAME(_assert)(const char *assertion, const char *file, unsigned int line) { auto ci = GetCrashInfoFromAssertion(assertion, file, line, nullptr); @@ -760,7 +760,7 @@ void RegisterPrettyTerminateHander() std::set_terminate(terminate_handler); } -#if !WIN32 +#if !defined(WIN32) static void HandlePosixSignal(int s) { if (s == SIGABRT && skipAbortSignal) { @@ -837,7 +837,7 @@ LONG WINAPI HandleWindowsException(EXCEPTION_POINTERS * ExceptionInfo) void RegisterPrettySignalHandlers() { -#if WIN32 +#if defined(WIN32) SetUnhandledExceptionFilter(HandleWindowsException); #else const std::vector posix_signals = { @@ -853,7 +853,7 @@ void RegisterPrettySignalHandlers() SIGTRAP, // Trace/breakpoint trap SIGXCPU, // CPU time limit exceeded (4.2BSD) SIGXFSZ, // File size limit exceeded (4.2BSD) -#if __APPLE__ +#if defined(__APPLE__) SIGEMT, // emulation instruction executed #endif }; From 5a693a83388e66b88b6ae39c79920bdf79223fab Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 23 May 2023 02:19:19 +0300 Subject: [PATCH 6/6] fix: `__clang__` && `__APPLE__` for `__assert_rtn` --- src/stacktraces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stacktraces.cpp b/src/stacktraces.cpp index 59a096158513..0daa7b50d08d 100644 --- a/src/stacktraces.cpp +++ b/src/stacktraces.cpp @@ -557,7 +557,7 @@ extern "C" void __real___cxa_free_exception(void * thrown_exception) static auto f = (void(*)(void*))dlsym(RTLD_NEXT, "__cxa_free_exception"); return f(thrown_exception); } -#if defined(__clang__) +#if defined(__clang__) && defined(__APPLE__) extern "C" void __attribute__((noreturn)) __real___assert_rtn(const char *function, const char *file, int line, const char *assertion) { static auto f = (void(__attribute__((noreturn)) *) (const char*, const char*, int, const char*))dlsym(RTLD_NEXT, "__assert_rtn"); @@ -622,7 +622,7 @@ static __attribute__((noinline)) crash_info GetCrashInfoFromAssertion(const char return ci; } -#if defined(__clang__) +#if defined(__clang__) && defined(__APPLE__) extern "C" void __attribute__((noinline)) WRAPPED_NAME(__assert_rtn)(const char *function, const char *file, int line, const char *assertion) { auto ci = GetCrashInfoFromAssertion(assertion, file, line, function);