mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-24 13:06:14 +01:00
glib-private: Check for LSAN support at runtime when controlling it
GLib ignores various leaks that we don't consider as such (like the default gio modules) via the LSAN public interface, however those cases are always ignored when using a non-ASAN compiled glib is used by an ASAN-compiled binary. This makes all the GLib-related programs to fail because of false positive leaks. To avoid this, use the gcc extension for weak linking so that we can control ASAN and LSAN only if the symbols they provide are actually available at runtime.
This commit is contained in:
parent
d354b2f55e
commit
fb58d55187
@ -37,14 +37,51 @@
|
||||
/*
|
||||
* %_GLIB_ADDRESS_SANITIZER:
|
||||
*
|
||||
* Private macro defined if the AddressSanitizer is in use.
|
||||
* Private macro defined if the AddressSanitizer is in use by GLib itself.
|
||||
*/
|
||||
#define _GLIB_ADDRESS_SANITIZER
|
||||
|
||||
#include <sanitizer/lsan_interface.h>
|
||||
|
||||
/* If GLib itself is not compiled with ASAN sanitizer we may still want to
|
||||
* control it in case it's linked by the loading application, so we need to
|
||||
* do this check dynamically.
|
||||
* However MinGW doesn't support weak attribute properly (even if it advertises
|
||||
* it), so we ignore it in such case since it's not convenient to go through
|
||||
* dlsym().
|
||||
* Under MSVC we could use alternatename, but it doesn't seem to be as reliable
|
||||
* as we'd like: https://stackoverflow.com/a/11529277/210151 and
|
||||
* https://devblogs.microsoft.com/oldnewthing/20200731-00/?p=104024
|
||||
*/
|
||||
#elif defined (G_OS_UNIX) && g_macro__has_attribute (weak)
|
||||
|
||||
#define HAS_DYNAMIC_ASAN_LOADING
|
||||
|
||||
void __lsan_enable (void) __attribute__ ((weak));
|
||||
void __lsan_disable (void) __attribute__ ((weak));
|
||||
void __lsan_ignore_object (const void *p) __attribute__ ((weak));
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* g_leak_sanitizer_is_supported:
|
||||
*
|
||||
* Checks at runtime if LeakSanitizer is currently supported by the running
|
||||
* binary. This may imply that GLib itself is not compiled with sanitizer
|
||||
* but that the loading program is.
|
||||
*/
|
||||
static inline gboolean
|
||||
g_leak_sanitizer_is_supported (void)
|
||||
{
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
return TRUE;
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
return __lsan_enable != NULL && __lsan_ignore_object != NULL;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* g_ignore_leak:
|
||||
* @p: any pointer
|
||||
@ -57,9 +94,12 @@
|
||||
static inline void
|
||||
g_ignore_leak (gconstpointer p)
|
||||
{
|
||||
#ifdef _GLIB_ADDRESS_SANITIZER
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
if (p != NULL)
|
||||
__lsan_ignore_object (p);
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
if (p != NULL && __lsan_ignore_object != NULL)
|
||||
__lsan_ignore_object (p);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -73,9 +113,11 @@ g_ignore_leak (gconstpointer p)
|
||||
static inline void
|
||||
g_ignore_strv_leak (GStrv strv)
|
||||
{
|
||||
#ifdef _GLIB_ADDRESS_SANITIZER
|
||||
gchar **item;
|
||||
|
||||
if (!g_leak_sanitizer_is_supported ())
|
||||
return;
|
||||
|
||||
if (strv)
|
||||
{
|
||||
g_ignore_leak (strv);
|
||||
@ -83,7 +125,6 @@ g_ignore_strv_leak (GStrv strv)
|
||||
for (item = strv; *item != NULL; item++)
|
||||
g_ignore_leak (*item);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -98,8 +139,11 @@ g_ignore_strv_leak (GStrv strv)
|
||||
static inline void
|
||||
g_begin_ignore_leaks (void)
|
||||
{
|
||||
#ifdef _GLIB_ADDRESS_SANITIZER
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
__lsan_disable ();
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
if (__lsan_disable != NULL)
|
||||
__lsan_disable ();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -112,11 +156,16 @@ g_begin_ignore_leaks (void)
|
||||
static inline void
|
||||
g_end_ignore_leaks (void)
|
||||
{
|
||||
#ifdef _GLIB_ADDRESS_SANITIZER
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
__lsan_enable ();
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
if (__lsan_enable != NULL)
|
||||
__lsan_enable ();
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef HAS_DYNAMIC_ASAN_LOADING
|
||||
|
||||
GMainContext * g_get_worker_context (void);
|
||||
gboolean g_check_setuid (void);
|
||||
GMainContext * g_main_context_new_with_next_id (guint next_id);
|
||||
|
Loading…
Reference in New Issue
Block a user