Debug and analyze

Use the dependencies and toolchain from Build from source. For each build below, start from the repository root and reuse the same Python and dependency paths, including CMAKE_PREFIX_PATH.

Debug with gdb

Create a separate Debug build:

mkdir debug
cd debug
cmake .. -GNinja \
  -DPython3_EXECUTABLE=/path/to/venv/bin/python \
  -DCMAKE_BUILD_TYPE=Debug
ninja

To pass the correct Python executable to gdb, print its path from the activated environment:

python -c 'import sys; print(sys.executable)'

Use the printed path below. From the debug build directory, point Python to the freshly built module:

PYTHONPATH="$PWD/py/src" \
  gdb --args /path/to/venv/bin/python path/to/script.py

At the gdb prompt, enter run. After a crash, enter bt for a backtrace.

For a C++ test, use CTest to print its executable and arguments:

ctest -N -V -R 'TestNamePattern'

Then run the reported executable in gdb. A single GoogleTest can be selected as follows:

gdb ./bin/UnitTestBase
(gdb) run --gtest_filter=SuiteName.TestName

clang-tidy

BA_TIDY=ON requires Clang and BA_PYTHON=OFF. Use a new build directory because the compiler cannot be changed in an existing CMake cache:

mkdir tidy
cd tidy
CC=clang CXX=clang++ cmake .. -GNinja -DBA_TIDY=ON -DBA_PYTHON=OFF
ninja

Address and undefined-behavior sanitizers

BA_SANITIZE=ON enables AddressSanitizer and UndefinedBehaviorSanitizer in a Linux Debug build:

mkdir asan
cd asan
cmake .. -GNinja \
  -DPython3_EXECUTABLE=/path/to/venv/bin/python \
  -DCMAKE_BUILD_TYPE=Debug \
  -DBA_SANITIZE=ON \
  -DBA_TESTS=OFF
ninja

For a GCC build, preload both runtimes when running a Python script from the build directory. Leak detection is disabled because it mainly reports Python allocations:

LIBASAN=$(gcc -print-file-name=libasan.so)
LIBUBSAN=$(gcc -print-file-name=libubsan.so)
LD_PRELOAD="$LIBASAN $LIBUBSAN" ASAN_OPTIONS=detect_leaks=0 \
  PYTHONPATH="$PWD/py/src" /path/to/venv/bin/python path/to/script.py

Valgrind

Valgrind is incompatible with AddressSanitizer. In a Debug build without BA_SANITIZE, run:

valgrind --leak-check=full --show-leak-kinds=definite,indirect \
  --track-origins=yes --error-limit=no ./bin/UnitTestBase