[gtk/matthiasc/for-master: 2/6] widget: Improve automatic component tracking



commit e6b2b27ec08820b215281aeebb344e281296a7dc
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun May 10 12:50:28 2020 -0400

    widget: Improve automatic component tracking
    
    Print out when components get finalized 'too late', e.g.
    in an idle after dispose. This happens sometimes, and
    it is useful to differentiate this situation from an
    actual, permanent leak.
    
    One example where this shows up is the property action
    in examples/exampleapplication9, which keeps a label
    alive until the actions are unexported on the bus,
    in an idle.

 gtk/gtkwidget.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 15c775aa44..ec9415c215 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -7220,6 +7220,7 @@ typedef struct {
   GType                widget_type;
   GObject             *object;
   gboolean             did_finalize;
+  gboolean             too_late;
 } FinalizeAssertion;
 
 static void
@@ -7228,7 +7229,15 @@ finalize_assertion_weak_ref (gpointer data,
 {
   FinalizeAssertion *assertion = (FinalizeAssertion *)data;
   assertion->did_finalize = TRUE;
+  if (assertion->too_late)
+    {
+      g_critical ("Automated component '%s' of class '%s' finalized after gtk_widget_destroy().\n",
+                  assertion->child_class->name,
+                  g_type_name (assertion->widget_type));
+      g_slice_free (FinalizeAssertion, assertion);
+    }
 }
+
 #endif /* G_ENABLE_CONSISTENCY_CHECKS */
 
 static void
@@ -7304,18 +7313,21 @@ gtk_widget_real_destroy (GtkWidget *object)
 
 #ifdef G_ENABLE_CONSISTENCY_CHECKS
       for (l = assertions; l; l = l->next)
-       {
-         FinalizeAssertion *assertion = l->data;
-
-         if (!assertion->did_finalize)
-           g_critical ("Automated component '%s' of class '%s' did not finalize in gtk_widget_destroy(). "
-                       "Current reference count is %d",
-                       assertion->child_class->name,
-                       g_type_name (assertion->widget_type),
-                       assertion->object->ref_count);
+        {
+          FinalizeAssertion *assertion = l->data;
 
-         g_slice_free (FinalizeAssertion, assertion);
-       }
+          if (!assertion->did_finalize)
+            {
+              g_critical ("Automated component '%s' of class '%s' did not finalize in gtk_widget_destroy(). "
+                          "Current reference count is %d",
+                          assertion->child_class->name,
+                          g_type_name (assertion->widget_type),
+                          assertion->object->ref_count);
+              assertion->too_late = TRUE;
+            }
+          else
+            g_slice_free (FinalizeAssertion, assertion);
+        }
       g_slist_free (assertions);
 #endif /* G_ENABLE_CONSISTENCY_CHECKS */
 


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