With an ASan build on Debian 12 or Ubuntu 22.04 (and probably others),
some tests (test-query-trace-info.sh, test-python-bt2.sh), fail because
of what boils down to this:
$ /home/smarchi/src/babeltrace/tests/utils/run-in-py-env.sh python3 /home/smarchi/src/babeltrace/tests/plugins/src.ctf.fs/query/test_query_trace_info.py
..AddressSanitizer: CHECK failed: asan_interceptors.cpp:320 "((__interception::real___cxa_throw)) != (0)" (0x0, 0x0) (tid=139166)
#0 0x7fc2bbf9b2aa in CheckUnwind ../../../../src/libsanitizer/asan/asan_rtl.cpp:67
#1 0x7fc2bbfbbc55 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) ../../../../src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:86
#2 0x7fc2bbf22924 in __interceptor___cxa_throw ../../../../src/libsanitizer/asan/asan_interceptors.cpp:320
#3 0x7fc2b8f5ea05 in void bt2c::Logger::logErrorAndThrow<true, bt2c::Error, char*&>(char const*, char const*, unsigned int, char const*, char*&) const /home/smarchi/src/babeltrace/src/cpp-common/bt2c/logging.hpp:316
#4 0x7fc2b8f5ea05 in read_src_fs_parameters(bt2::CommonMapValue<bt_value const>, bt2c::Logger const&) /home/smarchi/src/babeltrace/src/plugins/ctf/fs-src/fs.cpp:1516
#5 0x7fc2b903e4ca in trace_infos_query(bt2::CommonMapValue<bt_value const>, bt2c::Logger const&) /home/smarchi/src/babeltrace/src/plugins/ctf/fs-src/query.cpp:168
#6 0x7fc2b9019206 in ctf_fs_query(bt_self_component_class_source*, bt_private_query_executor*, char const*, bt_value const*, void*, bt_value const**) /home/smarchi/src/babeltrace/src/plugins/ctf/fs-src/fs.cpp:1609
#7 0x7fc2b980eed0 in bt_query_executor_query /home/smarchi/src/babeltrace/src/lib/graph/query-executor.c:221
#8 0x7fc2ba2d8c86 in _wrap_query_executor_query bt2/native_bt.c:19262
#9 0x5458a2 in cfunction_vectorcall_O ../Objects/methodobject.c:514
... lots of Python stack frames ...
#75 0x64f90e in pymain_run_file_obj ../Modules/main.c:360
#76 0x64f90e in pymain_run_file ../Modules/main.c:379
#77 0x64f90e in pymain_run_python ../Modules/main.c:601
#78 0x64f90e in Py_RunMain ../Modules/main.c:680
#79 0x6275c6 in Py_BytesMain ../Modules/main.c:734
#80 0x7fc2bbbf0249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#81 0x7fc2bbbf0304 in __libc_start_main_impl ../csu/libc-start.c:360
#82 0x627460 in _start (/usr/bin/python3.11+0x627460)
The problem is documented here [1].
The summary is (to the best of my understanding):
- we run python3 with a script that imports the bt2 Python module,
which eventually loads libbabeltrace2.so
- libbabeltrace2.so is built with ASan, so depends on libasan.so
- if we just try to run this as is, libasan.so complains that it's not
the first loaded shared library, so we LD_PRELOAD it
- now, when libasan.so is initialized, libstdc++ is not loaded, so some
things related to C++ (like the __interception::real___cxa_throw
variable) are not initialized
- libbabeltrace2.so and libstdc++.so are eventually loaded, something
in the test happens to throw an exception
- this is intercepted by libasan.so (through symbol interposition of
__cxa_throw I suppose)
- the assertion that real___cxa_throw must not be NULL fails
Debian and Ubuntu systems are affected because of their use of
-Wl,--as-needed. The build system of ASan makes libasan.so link against
libstdc++ (to ensure that libstdc++ is loaded along with libasan.so),
but that dependency is dropped du to -Wl,--as-needed.
A solution I used during development (and this is why I failed to see
the problem sooner I suppose) was to add a libstdc++ dependency in
/usr/bin/python3. This is obviously not possible at large.
The only applicable solution I see to keep ASan builds working is to
LD_PRELOAD libstdc++.so along with libasan.so. This emulates the
missing libasan.so -> libstdc++.so dependency.
[1] https://github.com/google/sanitizers/issues/934
Change-Id: I10c53347167a7f68cb2fb2e8c08a98ff2b638ffc
Reviewed-on: https://review.lttng.org/c/babeltrace/+/12446
Reviewed-by: Michael Jeanson <mjeanson@efficios.com>
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
if [[ ${BT_TESTS_ENABLE_ASAN:-} == 1 ]]; then
if $BT_TESTS_CC_BIN --version | head -n 1 | bt_grep -q '^gcc'; then
local -r lib_asan=$($BT_TESTS_CC_BIN -print-file-name=libasan.so)
- local -x LD_PRELOAD=$lib_asan${LD_PRELOAD:+:}${LD_PRELOAD:-}
+ local -r lib_stdcxx=$($BT_TESTS_CC_BIN -print-file-name=libstdc++.so)
+ local -x LD_PRELOAD=$lib_asan:$lib_stdcxx${LD_PRELOAD:+:}${LD_PRELOAD:-}
fi
local -x ASAN_OPTIONS=${ASAN_OPTIONS:-}${ASAN_OPTIONS:+,}detect_leaks=0