[glib/ebassi/floating-warning] Add a (diagnostic) warning for finalized floating objects




commit 6fe0f983607e868ed3847e781727c9912429f73e
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Sep 14 16:09:22 2021 +0100

    Add a (diagnostic) warning for finalized floating objects
    
    GTK currently checks if a GtkWidget is finalized while still using a
    floating reference—i.e. a widget was disposed without any parent
    container owning it.
    
    This warning can be useful to identify and trace ownership transfer
    issues in libraries using initially unowned floating object types.
    
    To avoid introducing constraints ex post, we can gate this check behind
    both the G_ENABLE_DEBUG compile time flag for GLib, and behind the
    G_ENABLE_DIAGNOSTIC environment variable run time check.
    
    Fixes: #2489

 gobject/gobject.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 9776d7c95..2d950a687 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -1180,6 +1180,24 @@ g_object_real_dispose (GObject *object)
   g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
 }
 
+static gboolean
+floating_check (GObject *object)
+{
+  static const char *g_enable_diagnostic = NULL;
+
+  if (G_UNLIKELY (g_enable_diagnostic == NULL))
+    {
+      g_enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC");
+      if (g_enable_diagnostic == NULL)
+        g_enable_diagnostic = "0";
+    }
+
+  if (g_enable_diagnostic[0] == '1')
+    return g_object_is_floating (object);
+
+  return FALSE;
+}
+
 static void
 g_object_finalize (GObject *object)
 {
@@ -1189,6 +1207,17 @@ g_object_finalize (GObject *object)
                   G_OBJECT_TYPE_NAME (object), object);
     }
 
+#ifdef G_ENABLE_DEBUG
+ if (floating_check (object))
+   {
+      g_critical ("A floating object %s %p was finalized. This means that someone\n"
+                  "called g_object_unref() on an object that had only a floating\n"
+                  "reference; the initial floating reference is not owned by anyone\n"
+                  "and must be removed with g_object_ref_sink().",
+                  G_OBJECT_TYPE_NAME (object), object);
+   }
+#endif
+
   g_datalist_clear (&object->qdata);
   
   GOBJECT_IF_DEBUG (OBJECTS,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]