GNOME Bugzilla – Bug 455900
invalid write on gtkfilechooserdefault finalise
Last modified: 2012-02-15 15:09:28 UTC
I got this one in epiphany by printing to a file (File->Print, switch to File printer, Print). It doesn't seem to happen every time, but I got it twice in 4 valgrind runs. ==2142== Invalid write of size 4 ==2142== at 0x4E1F6B9: g_nullify_pointer (gutils.c:3105) ==2142== by 0x4D90EE0: weak_refs_notify (gobject.c:1466) ==2142== by 0x4DE0716: g_datalist_id_set_data_full (gdataset.c:242) ==2142== by 0x4D91598: g_object_real_dispose (gobject.c:534) ==2142== by 0x4D917CF: g_object_unref (gobject.c:1765) ==2142== by 0x46EB3CB: gtk_file_chooser_default_finalize (gtkfilechooserdefault.c:941) ==2142== by 0x4D9186C: g_object_unref (gobject.c:1793) ==2142== by 0x4D91CE7: g_object_run_dispose (gobject.c:574) ==2142== by 0x477D411: gtk_object_destroy (gtkobject.c:403) ==2142== by 0x489A694: gtk_widget_destroy (gtkwidget.c:2491) ==2142== by 0x465D90F: gtk_box_forall (gtkbox.c:799) ==2142== by 0x46A824A: gtk_container_foreach (gtkcontainer.c:1479) ==2142== by 0x46AA3C6: gtk_container_destroy (gtkcontainer.c:1020) ==2142== by 0x4D9CF48: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==2142== by 0x4D8DE26: g_type_class_meta_marshal (gclosure.c:567) ==2142== by 0x4D8F71B: g_closure_invoke (gclosure.c:490) ==2142== by 0x4DA181E: signal_emit_unlocked_R (gsignal.c:2556) ==2142== by 0x4DA24D2: g_signal_emit_valist (gsignal.c:2199) ==2142== by 0x4DA2784: g_signal_emit (gsignal.c:2243) ==2142== by 0x477DBAD: gtk_object_dispose (gtkobject.c:418) ==2142== by 0x489AFF0: gtk_widget_dispose (gtkwidget.c:7450) ==2142== by 0x4D91CDF: g_object_run_dispose (gobject.c:573) ==2142== by 0x477D411: gtk_object_destroy (gtkobject.c:403) ==2142== by 0x489A694: gtk_widget_destroy (gtkwidget.c:2491) ==2142== by 0x465D90F: gtk_box_forall (gtkbox.c:799) ==2142== by 0x46A824A: gtk_container_foreach (gtkcontainer.c:1479) ==2142== by 0x46AA3C6: gtk_container_destroy (gtkcontainer.c:1020) ==2142== by 0x4D9CF48: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==2142== by 0x4D8DE26: g_type_class_meta_marshal (gclosure.c:567) ==2142== by 0x4D8F71B: g_closure_invoke (gclosure.c:490) ==2142== Address 0x564152C is 68 bytes inside a block of size 100 free'd ==2142== at 0x402137F: free (vg_replace_malloc.c:233) ==2142== by 0x4DFA520: g_free (gmem.c:187) ==2142== by 0x4E0F3C6: g_slice_free1 (gslice.c:865) ==2142== by 0x4DAFA92: g_type_free_instance (gtype.c:1602) ==2142== by 0x4D91919: g_object_unref (gobject.c:1803) ==2142== by 0x489AE1C: gtk_widget_finalize (gtkwidget.c:7505) ==2142== by 0x4874DC0: gtk_tree_view_finalize (gtktreeview.c:1504) ==2142== by 0x4D9186C: g_object_unref (gobject.c:1793) ==2142== by 0x4D91CE7: g_object_run_dispose (gobject.c:574) ==2142== by 0x477D411: gtk_object_destroy (gtkobject.c:403) ==2142== by 0x489A694: gtk_widget_destroy (gtkwidget.c:2491) ==2142== by 0x46598A4: gtk_bin_forall (gtkbin.c:133) ==2142== by 0x47C1A35: gtk_scrolled_window_forall (gtkscrolledwindow.c:1021) ==2142== by 0x46A824A: gtk_container_foreach (gtkcontainer.c:1479) ==2142== by 0x46AA3C6: gtk_container_destroy (gtkcontainer.c:1020) ==2142== by 0x47C3AB8: gtk_scrolled_window_destroy (gtkscrolledwindow.c:799) ==2142== by 0x4D9CF48: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==2142== by 0x4D8DE26: g_type_class_meta_marshal (gclosure.c:567) ==2142== by 0x4D8F71B: g_closure_invoke (gclosure.c:490) ==2142== by 0x4DA181E: signal_emit_unlocked_R (gsignal.c:2556) ==2142== by 0x4DA24D2: g_signal_emit_valist (gsignal.c:2199) ==2142== by 0x4DA2784: g_signal_emit (gsignal.c:2243) ==2142== by 0x477DBAD: gtk_object_dispose (gtkobject.c:418) ==2142== by 0x489AFF0: gtk_widget_dispose (gtkwidget.c:7450) ==2142== by 0x4D91CDF: g_object_run_dispose (gobject.c:573) ==2142== by 0x477D411: gtk_object_destroy (gtkobject.c:403) ==2142== by 0x489A694: gtk_widget_destroy (gtkwidget.c:2491) ==2142== by 0x465D90F: gtk_box_forall (gtkbox.c:799) ==2142== by 0x46A824A: gtk_container_foreach (gtkcontainer.c:1479) ==2142== by 0x46AA3C6: gtk_container_destroy (gtkcontainer.c:1020) The line number in gtkfilechooserdefault is a bit off due to unrelated changes; line 941 is this one in _finalize: 940 if (impl->shortcuts_pane_filter_model) 941 g_object_unref (impl->shortcuts_pane_filter_model); gtk+ svn trunk, unix filechooser backend.
Still there, in gtk3-3.2.3-1.fc16, with this valgrind log from a gtk3-demo, just opening and immediately closing "Pickers" demo: ==23409== Invalid write of size 8 ==23409== at 0x38704786C5: g_nullify_pointer (gutils.c:3630) ==23409== by 0x3871411171: weak_refs_notify (gobject.c:2244) ==23409== by 0x38714113DA: g_object_unref (gobject.c:2709) ==23409== by 0x4D3111A: gtk_file_chooser_default_finalize (gtkfilechooserdefault.c:845) ==23409== by 0x387141145C: g_object_unref (gobject.c:2746) ==23409== by 0x4CC1923: gtk_box_forall (gtkbox.c:1856) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4CC1923: gtk_box_forall (gtkbox.c:1856) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4D2717B: gtk_file_chooser_button_destroy (gtkfilechooserbutton.c:938) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4D4C7EF: gtk_grid_forall (gtkgrid.c:503) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140EA23: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== Address 0xdbc3b30 is 128 bytes inside a block of size 200 free'd ==23409== at 0x4A0662E: free (vg_replace_malloc.c:366) ==23409== by 0x387044B792: g_free (gmem.c:263) ==23409== by 0x387046066E: g_slice_free1 (gslice.c:907) ==23409== by 0x38714318B3: g_type_free_instance (gtype.c:1930) ==23409== by 0x4EB2E02: gtk_widget_finalize (gtkwidget.c:10716) ==23409== by 0x387141145C: g_object_unref (gobject.c:2746) ==23409== by 0x4DE8E7D: gtk_scrolled_window_forall (gtkscrolledwindow.c:1265) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4CC1923: gtk_box_forall (gtkbox.c:1856) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4DB80BF: gtk_paned_forall (gtkpaned.c:1946) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4CC1923: gtk_box_forall (gtkbox.c:1856) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4CC1923: gtk_box_forall (gtkbox.c:1856) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388) ==23409== by 0x387142A140: g_signal_emit_valist (gsignal.c:3003) ==23409== by 0x387142A2E1: g_signal_emit (gsignal.c:3060) ==23409== by 0x4EBF5CD: gtk_widget_dispose (gtkwidget.c:10666) ==23409== by 0x3871413350: g_object_run_dispose (gobject.c:945) ==23409== by 0x4CC1923: gtk_box_forall (gtkbox.c:1856) ==23409== by 0x4D041CA: gtk_container_destroy (gtkcontainer.c:1370) ==23409== by 0x387140E979: g_closure_invoke (gclosure.c:774) ==23409== by 0x3871420777: signal_emit_unlocked_R (gsignal.c:3388)
This is odd; we never add a weak ref or weak pointer for impl->shortcuts_pane_filter_model. A quick grep for "weak" in gtk+/gtk/* doesn't yield anything obvious. Milan, that model is created in shortcuts_model_create(), during a call to shortcuts_pane_model_filter_new(). Could you set a breakpoint there, and then a conditional breakpoint on g_object_weak_ref() when the object in question is the shortcuts_pane_filter_model? Maybe that will lead us to whatever is weak-reffing it. Thanks!
Created attachment 207527 [details] [review] proposed gtk patch for gtk+; After some debugging with gtk3-demo I found the issue. The gtktreeviewaccessible.c is causing this, it adds a weak pointer on the model, but never removes it, and the trick is that the accessible is destroyed before the model. The git master of gtk+ doesn't suffer of this, but I didn't find a certain patch for it, basically because there is none, the tree view's accessible was totally rewritten and "just applying" all those changes doesn't work in 3.2.3. I would like to propose this change to 3.2.3, because this issue (rewriting NULL into "random" memory) seems to cause various issues in any gtk+ application which uses tree views and file choosers.
You've right that g_nullify_pointer() is not at all in gtk, thus I looked in glib and it yield me to g_object_add_weak_pointer/g_object_remove_weak_pointer, whose are basically the only users of that function. I realized that gtk+ code is "full" of g_object_add_weak_pointer(), but it misses its counterpart calls for the g_object_remove_weak_pointer(), in case the pointer was not nullyfied yet (which is basically this bug about).
Looks good; and thanks for checking the a11y subtree - hadn't thought of that. Please commit your patch!
Created commit 516bb1d in gtk-3-2 branch (3.2.4+)
Beautiful. Thanks for debugging this :)