# AddressSanitizer Leak Suppression File for Mudlet
# This file suppresses known leaks from third-party libraries that are
# typically one-time initialization leaks or false positives from library
# internal caching mechanisms.
#
# This file is embedded into sanitizer-enabled builds at compile time (see
# LsanSuppressions.h.in and __lsan_default_suppressions in main.cpp), so
# testing/PTB builds apply it automatically. To supply additional
# suppressions at runtime:
#   export LSAN_OPTIONS=suppressions=/path/to/asan-suppressions.txt
#
# Prefer listing the modules that ALLOCATE the leaked memory (graphics
# drivers, font stacks, theme engines). Be wary of adding libraries that
# appear mid-stack while dispatching events into Mudlet code (libX11, libxcb,
# Qt modules) - a suppression matches if ANY frame does, so those can hide
# genuine Mudlet leaks too.
#
# A leak: line can only match a frame that still resolves to a module path or a
# symbol name. Leaks reported as "<unknown module>" with no symbols cannot be
# matched by any leak: line: the allocating library was dlclose()d (or the code
# was JITed) before LeakSanitizer runs at exit, so there is no name left to
# compare against. Those have to be handled at their source, not here - see the
# GPU driver note below for the recurring example.
#
# Do not suppress a Qt allocation primitive to quieten a report. By default
# AddressSanitizer captures allocation stacks with the frame-pointer unwinder,
# and the Qt binaries CI installs are built without frame pointers, so the walk
# stops at the first Qt frame. Every leaked QString in the program then reports
# as the same three-frame stack
#   malloc / allocateHelper / QArrayData::allocate2
# with no caller to identify it, and every leaked QByteArray as the allocate1
# equivalent. Suppressing those symbols hides the whole class - which is what
# `leak:QArrayData::allocate2` did here until it was removed. To get the real
# callers of such a report, re-run with the accurate unwinder:
#   ASAN_OPTIONS=fast_unwind_on_malloc=0:malloc_context_size=30
# It costs roughly 3x the runtime of the test run, which is why CI does not use
# it by default, but the stacks it produces name the leaking function.
#
# See: https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer

# ==============================================================================
# GPU driver leaks
# One-time initialization allocations in the NVIDIA driver (cuInit is invoked
# via FFmpeg/Qt Multimedia) and in Mesa's DRI drivers
# ==============================================================================
leak:libcuda.so
leak:nvidia
leak:_dri.so

# leak:_dri.so above can only match when the driver is still mapped at process
# exit, where LeakSanitizer runs its check. Mesa dlopen()s a DRI driver on first
# GL use and dlclose()s it when the last GL context - e.g. the 3D map view's
# QOpenGLWidget - is torn down. A driver-init allocation that leaks and is then
# unloaded before exit is reported as "<unknown module>" (the .so is gone by the
# time LeakSanitizer runs), so NO leak: line can match it. On the CI leak job
# (Ubuntu 22.04) this recurs as a small (~240 byte) realloc+calloc leak during
# mudlet teardown and flakes across unrelated PRs; it does not reproduce on newer
# Mesa. Do not try to silence it with a leak: line here (there is no name to
# match) - keep the GL context from being created/destroyed under the sanitizer
# test-side instead, as PR #9534 did for the show3dMapView test.
#
# A second failure on the same CI job was never suppressible either, and is fixed
# elsewhere rather than here (#9809): LeakSanitizer's stop-the-world tracer - the
# helper process that ptrace-attaches at exit to scan memory for live pointers -
# took SIGSEGV, and the run ended with
#   Tracer caught signal 11: addr=0x... pc=0x... sp=0x...
#   ==NNNNN==LeakSanitizer has encountered a fatal error.
# straight after the test body reported itself green, and with no leak report at
# all (run 31428353403 on TelnetTextDisplayedTest, run 31867450938 on four more).
#
# Nothing in this file can reach it: suppressions filter leak *reports*, and this
# aborts before reporting begins. The cause is not a leak either - up to GCC 13
# and LLVM 16 the sanitizer runtime misreads where a dynamic TLS block starts and
# how long it is, and the tracer dies scanning the garbage range that leaves.
# intercept_tls_get_addr=0 stops the misreading; test/functional_tests/
# CMakeLists.txt has the mechanism and names every place the flag is set.

# ==============================================================================
# Fontconfig library leaks
# These are typically one-time initialization leaks in the font system
# ==============================================================================
leak:libfontconfig.so

# ==============================================================================
# Pango text rendering library leaks
# These include pango, pangocairo, and pangoft2 leaks
# ==============================================================================
leak:libpango-1.0.so
leak:libpangocairo-1.0.so
leak:libpangoft2-1.0.so

# ==============================================================================
# GTK3 GUI toolkit leaks
# These are often related to widget initialization and theme loading
# ==============================================================================
leak:libgtk-3.so

# ==============================================================================
# Cairo graphics library leaks
# ==============================================================================
leak:libcairo.so

# ==============================================================================
# HarfBuzz text shaping library leaks
# ==============================================================================
leak:libharfbuzz.so

# ==============================================================================
# GLib/GObject library leaks
# These are from the GLib object system and utilities
# ==============================================================================
leak:libglib-2.0.so
leak:libgobject-2.0.so

# ==============================================================================
# Expat XML parser library leaks
# ==============================================================================
leak:libexpat.so

# ==============================================================================
# speech-dispatcher client library leak
# One-time allocation in the speech-dispatcher client (libspeechd) when its
# connection is first opened, reached via QtTextToSpeech's speechd engine.
# Only surfaces when a speech-dispatcher daemon is reachable and something
# touches the tts* API; no Mudlet frames are involved.
# ==============================================================================
leak:libspeechd.so

# ==============================================================================
# Qt internal leaks (Qt's integration with system libraries)
# These are typically initialization leaks in Qt's platform integration
# ==============================================================================

# Qt's GTK3 platform theme integration
leak:QGtk3Interface::widget

# Qt's fontconfig database integration
leak:QFontconfigDatabase::addApplicationFont
leak:QFontEngineMultiFontConfig

# Qt translation system (one-time initialization)
leak:QTranslatorPrivate::do_load

# ==============================================================================
# OpenSSL 3 provider initialization leaks
# One-time allocations made when Qt's OpenSSL TLS backend loads the default
# provider on first TLS use; seen with Qt 6.12's qtlsbackend_openssl
# ==============================================================================
leak:OSSL_PROVIDER_try_load
leak:OSSL_DECODER_do_all_provided
