From a325fdbb5542f3db618a5b521fd5cc76f01a7a3c Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 12 Aug 2026 15:05:34 -0500 Subject: [PATCH 1/2] test: suppress QDBus watcher QThread leak in lsan The extended Qt suppressions from #7576 cover QDBusConnectionPrivate, QDBusConnectionManager and QLayoutPrivate, but the connection manager also lazily spawns a watcher QThread whose 120-byte allocation reports with only the QThread constructor frame, still failing test_dash-qt under asan on develop. --- test/sanitizer_suppressions/lsan | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/sanitizer_suppressions/lsan b/test/sanitizer_suppressions/lsan index 1f21de07afd5..6c0ec81977d1 100644 --- a/test/sanitizer_suppressions/lsan +++ b/test/sanitizer_suppressions/lsan @@ -3,3 +3,7 @@ leak:libQt5Widgets leak:QDBusConnectionPrivate leak:QDBusConnectionManager leak:QLayoutPrivate +# QDBusConnectionManager lazily spawns a watcher QThread that is never joined +# before process exit; the manager itself is suppressed above but the thread +# object's allocation carries only the QThread constructor frame. +leak:QThread::QThread From aa6eaa8b79a8e46a8c2f5058e930214eb88a0c09 Mon Sep 17 00:00:00 2001 From: pasta Date: Thu, 13 Aug 2026 15:18:05 -0500 Subject: [PATCH 2/2] test: suppress leaks from Qt binaries Adapt the approach from bitcoin/bitcoin#35937 so Qt's process-global leaks do not require broad shared-symbol suppressions. Hide the suppression summary in both CI entry points that load the LSan rules. --- ci/dash/matrix.sh | 2 +- ci/test/04_install.sh | 2 +- test/sanitizer_suppressions/lsan | 10 ++-------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index 49117d71c82f..e54e279422c4 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -12,7 +12,7 @@ source ./ci/test/00_setup_env.sh # Configure sanitizers options export ASAN_OPTIONS="detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" -export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan" +export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan:print_suppressions=0" export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1" export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh index dbe478598b11..992d1ed19b17 100755 --- a/ci/test/04_install.sh +++ b/ci/test/04_install.sh @@ -15,7 +15,7 @@ mkdir -p "${CCACHE_DIR}" mkdir -p "${PREVIOUS_RELEASES_DIR}" export ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" -export LSAN_OPTIONS="suppressions=${BASE_BUILD_DIR}/test/sanitizer_suppressions/lsan" +export LSAN_OPTIONS="suppressions=${BASE_BUILD_DIR}/test/sanitizer_suppressions/lsan:print_suppressions=0" export TSAN_OPTIONS="suppressions=${BASE_BUILD_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1" export UBSAN_OPTIONS="suppressions=${BASE_BUILD_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" env | grep -E '^(BASE_|QEMU_|CCACHE_|LC_ALL|BOOST_TEST_RANDOM|DEBIAN_FRONTEND|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS|PREVIOUS_RELEASES_DIR))' | tee /tmp/env diff --git a/test/sanitizer_suppressions/lsan b/test/sanitizer_suppressions/lsan index 6c0ec81977d1..1c6865aca1c2 100644 --- a/test/sanitizer_suppressions/lsan +++ b/test/sanitizer_suppressions/lsan @@ -1,9 +1,3 @@ # Suppress warnings triggered in dependencies -leak:libQt5Widgets -leak:QDBusConnectionPrivate -leak:QDBusConnectionManager -leak:QLayoutPrivate -# QDBusConnectionManager lazily spawns a watcher QThread that is never joined -# before process exit; the manager itself is suppressed above but the thread -# object's allocation carries only the QThread constructor frame. -leak:QThread::QThread +leak:test_dash-qt +leak:dash-qt