From b3d0d73c5875990fc62c25a1f7e81e8d0c941067 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Fri, 5 Sep 2025 17:42:30 +0800 Subject: [PATCH] qa/{asan,lsan}.supp: suppress Python module and libstdc++ false positives Add suppression rules for two categories of false positive warnings encountered during ASan-enabled testing: 1. PyModule_ExecDef memory leaks: ASan incorrectly interprets Python's module loading behavior as memory leaks when the interpreter loads extension modules. 2. __cxa_throw interception failures: ASan's interceptor cannot properly intercept exception handling when libstdc++.so is loaded after the ASan shared library, causing CHECK failures. 3. ErasureCodePluginRegistry::load: `ceph::ErasureCodePluginRegistry::load()` is known to leak, as we don't free the memory allocated by the ec plugins which are registered in the `ErasureCodePluginRegistry` singleton. this is a known issue, but since the `ErasureCodePluginRegistry` instance is a singleton. we can live with it. in this change, we add the rule to suppress the leak report from LeakSanitizer. this rule also exist in qa/valgrind.supp. All warnings are confirmed false positives that should be suppressed to reduce noise in test output. Example warnings: ``` Direct leak of 3264 byte(s) in 1 object(s) allocated from: #0 0x7f6027d20cb5 in malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:67 #1 0x7f60277557ad (/usr/lib/libpython3.13.so.1.0+0x1557ad) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #2 0x7f6027756067 (/usr/lib/libpython3.13.so.1.0+0x156067) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #3 0x7f60278471a0 (/usr/lib/libpython3.13.so.1.0+0x2471a0) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #4 0x7f602774d031 (/usr/lib/libpython3.13.so.1.0+0x14d031) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #5 0x7b60234093bb in __Pyx_modinit_type_init_code.constprop.0 /home/kefu/dev/ceph/build/src/pybind/rados/rados.c:82066 #6 0x7b602340a826 in __pyx_pymod_exec_rados /home/kefu/dev/ceph/build/src/pybind/rados/rados.c:82755 #7 0x7f6027856777 in PyModule_ExecDef (/usr/lib/libpython3.13.so.1.0+0x256777) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #8 0x7f602785baa3 (/usr/lib/libpython3.13.so.1.0+0x25baa3) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #9 0x7f6027793df2 (/usr/lib/libpython3.13.so.1.0+0x193df2) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #10 0x7f6027777cbe in _PyEval_EvalFrameDefault (/usr/lib/libpython3.13.so.1.0+0x177cbe) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #11 0x7f60277957de (/usr/lib/libpython3.13.so.1.0+0x1957de) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #12 0x7f60277d11b9 in PyObject_CallMethodObjArgs (/usr/lib/libpython3.13.so.1.0+0x1d11b9) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #13 0x7f60277d0ee4 in PyImport_ImportModuleLevelObject (/usr/lib/libpython3.13.so.1.0+0x1d0ee4) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #14 0x7f6027779c0c in _PyEval_EvalFrameDefault (/usr/lib/libpython3.13.so.1.0+0x179c0c) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #15 0x7f602784e2c8 in PyEval_EvalCode (/usr/lib/libpython3.13.so.1.0+0x24e2c8) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #16 0x7f602788c88b (/usr/lib/libpython3.13.so.1.0+0x28c88b) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #17 0x7f602788985c (/usr/lib/libpython3.13.so.1.0+0x28985c) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #18 0x7f6027886f57 (/usr/lib/libpython3.13.so.1.0+0x286f57) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #19 0x7f6027886211 (/usr/lib/libpython3.13.so.1.0+0x286211) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #20 0x7f6027885b82 (/usr/lib/libpython3.13.so.1.0+0x285b82) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #21 0x7f6027883e50 in Py_RunMain (/usr/lib/libpython3.13.so.1.0+0x283e50) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #22 0x7f602783bbea in Py_BytesMain (/usr/lib/libpython3.13.so.1.0+0x23bbea) (BuildId: bea05fc2c8bd66145b159f10dcd810ebe813af39) #23 0x7f6027227674 (/usr/lib/libc.so.6+0x27674) (BuildId: 4fe011c94a88e8aeb6f2201b9eb369f42b4a1e9e) #24 0x7f6027227728 in __libc_start_main (/usr/lib/libc.so.6+0x27728) (BuildId: 4fe011c94a88e8aeb6f2201b9eb369f42b4a1e9e) #25 0x55dae17e6044 in _start (/usr/bin/python3.13+0x1044) (BuildId: 8c0dc848f5b978c56ebeb07255bb332b4b37ae4e) ``` ``` AddressSanitizer: CHECK failed: asan_interceptors.cpp:335 "((__interception::real___cxa_throw)) != (0)" (0x0, 0x0) (tid=3246455) #0 0x7f345ea81979 in CheckUnwind ../../../../src/libsanitizer/asan/asan_rtl.cpp:69 #1 0x7f345eaa790d in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) ../../../../src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:86 #2 0x7f345e9e1d54 in __interceptor___cxa_throw ../../../../src/libsanitizer/asan/asan_interceptors.cpp:335 #3 0x7f345e9e1d54 in __interceptor___cxa_throw ../../../../src/libsanitizer/asan/asan_interceptors.cpp:334 #4 0x7f3458623def in void boost::throw_exception(boost::bad_lexical_cast const&) /opt/ceph/include/boost/throw_exception.hpp:165 #5 0x7f345997ad3b in void boost::conversion::detail::throw_bad_cast, std::allocator >, unsigned long>() /opt/ceph/include/boost/lexical_cast/bad_lexical_cast.hpp:93 #6 0x7f3459979d35 in unsigned long boost::lexical_cast, std::allocator > >(std::__cxx11::basic_string, std::allocator > const&) /opt/ceph/include/boost/lexical_cast.hpp:43` ``` Signed-off-by: Kefu Chai --- cmake/modules/AddCephTest.cmake | 2 +- qa/asan.supp | 3 +++ qa/lsan.supp | 6 ++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 qa/asan.supp diff --git a/cmake/modules/AddCephTest.cmake b/cmake/modules/AddCephTest.cmake index 7c40f831f61..245747d08c7 100644 --- a/cmake/modules/AddCephTest.cmake +++ b/cmake/modules/AddCephTest.cmake @@ -32,7 +32,7 @@ function(add_ceph_test test_name test_path) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT - ASAN_OPTIONS=detect_odr_violation=0 + ASAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/qa/asan.supp,detect_odr_violation=0 LSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/qa/lsan.supp,print_suppressions=0) endif() set_property(TEST ${test_name} diff --git a/qa/asan.supp b/qa/asan.supp new file mode 100644 index 00000000000..fda9b6ae795 --- /dev/null +++ b/qa/asan.supp @@ -0,0 +1,3 @@ +# ASan's interceptor is not able to find the real throw function because of +# https://github.com/google/sanitizers/issues/934 +interceptor_via_fun:__interceptor___cxa_throw diff --git a/qa/lsan.supp b/qa/lsan.supp index c7d6cf59ed1..055a703b0fc 100644 --- a/qa/lsan.supp +++ b/qa/lsan.supp @@ -28,3 +28,9 @@ leak:^PyUnicode_New # python3.9, 3.10, 3.11 leak:^PyMem_Malloc # python3.12 doesn't leak anything +# python3.13 +leak:^PyModule_ExecDef + +# following suppression mirrors qa/valgrind.supp +# ignore ec plugin factory (FIXME SOMEDAY) +leak:^ceph::ErasureCodePluginRegistry::load -- 2.39.5