Setting a property between dispose and finalize

According to the GObject reference manual, object methods should be able to run without program error after their object has been disposed but before it has been finalized. I would like to know whether this implies that an object should not produce critical warnings between disposal and finalization if one of its properties is set.

Here is the situation: I have a GtkFontButton whose “font” property is bound to a setting using g_settings_bind. Due to the language bindings, the GtkFontButton is disposed but not immediately finalized. In this period, the setting can change causing the “font” property to be set. The backtrace from gdb shows that the following critical warnings occur due to an attempt to set the “font” property while the GtkFontButton is disposed:

(app-polyml:22680): Gtk-CRITICAL **: gtk_label_set_text: assertion ‘GTK_IS_LABEL (label)’ failed

(app-polyml:22680): Gtk-CRITICAL **: gtk_label_set_text: assertion ‘GTK_IS_LABEL (label)’ failed

(app-polyml:22680): Gtk-CRITICAL **: gtk_widget_get_style_context: assertion ‘GTK_IS_WIDGET (widget)’ failed

My suspicion is that some private data is freed on disposal but the widget still tries to use it due to a change in the property “font” that calls the following function hierarchy:

Is this an issue with GtkFontButton or is an application expected to unbind the setting from the “font” property to protect against this, e.g. in a “destroy” signal handler for the GtkFontButton instance?

That’s correct, it would be a bug if it crashes or causes critical warnings. It is allowed to cleanly fail any operations in that time, with emphasis on cleanly.

So what you see here looks like a bug in GtkFontButton.

1 Like

Thanks for confirming. I was about to raise an issue but thought I would look at how other widgets using gtk_widget_class_bind_template_child_private protect against use of private state after disposal . Looking at GtkAboutDialog, I can’t see how this is done. Testing with the code below suggests that gtk_about_dialog_set_version produces critical warnings after disposal (but not if there is no disposal). Is the test code below in some way flawed?

/* gcc test_set_after_dispose.c `pkg-config --cflags --libs gtk+-3.0` */

#include <gtk/gtk.h>

int main (int argc, gchar *argv[])
  GtkWidget *about;

  gtk_init (&argc, &argv);

  about = gtk_about_dialog_new ();
  g_object_ref_sink (about);

  gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (about), "1.2.3");

  gtk_widget_realize (about);

/* Should uncommenting this disposal expression affect the subsequent
 * `gtk_about_dialog_set_version` ?  I didn't think so but doing so
 * results in critical warnings from `gtk_about_dialog_set_version`.

  g_object_run_dispose (G_OBJECT (about));


  gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (about), "2.3.4"); 

  g_object_unref (about);

  return 0;

I’m not a GTK developer but that seems wrong to me. Best to create an issue for all these things. Especially because it actually means a problem in practice for bindings this seems like something that should be fixed.

Also more developers should run their code with G_DEBUG=fatal_criticals :wink:

Thanks @sdroege . I have raised an issue for this.

+1 for G_DEBUG=fatal-criticals!

1 Like

Which language bindings are you using btw?

I’m using SML bindings provided by Giraffe Library.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.