After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 540201 - Hard crash trying to use gtk_tree_model_iter_has_child in the GtkTreeModelFilter visible function callback
Hard crash trying to use gtk_tree_model_iter_has_child in the GtkTreeModelFil...
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkTreeView
2.12.x
Other All
: High critical
: ---
Assigned To: gtktreeview-bugs
gtktreeview-bugs
Depends on:
Blocks: 539897
 
 
Reported: 2008-06-25 19:24 UTC by Snark
Modified: 2009-09-05 15:26 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Snark 2008-06-25 19:24:01 UTC
I tried to make some rows invisible in a GtkTreeModelFilter, based on whether they have children or not. The code is organized like this ; first I set a visible function :
   gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
					  tree_model_filter_hide_show_offline,
					  self, NULL);

then in that callback function, I do :
   result = gtk_tree_model_iter_has_child (model, iter);
where I got both model and filter as arguments, so hopefully they match.

And this call to gtk_tree_model_iter_has_child gives the following error :
**
** Gtk:ERROR:(/tmp/buildd/gtk+2.0-2.12.10/gtk/gtktreemodelfilter.c:1583):gtk_tree_model_filter_row_has_child_toggled: assertion failed: (elt->visible)

if I replace the line with result = TRUE, then no problem, so I'm sure it's this call which gives issues.
Comment 1 Charles Day 2008-08-14 04:19:48 UTC
I see the same error message. The steps leading to the crash in my case are:

1. A node with no children exists in the child model, and a corresponding node exists in the GtkTreeModelFilter but is not visible (elt->visible is FALSE).

2. Adding a first child to the node in the child model causes the child model to signal "row_inserted" on the child, followed by "row_has_child_toggled" on the parent.

3. The GtkTreeModelFilter's handler for the "row_has_child_toggled" signal, gtk_tree_model_filter_row_has_child_toggled(), gets called. When it checks to see if the parent is visible by calling gtk_tree_model_filter_visible() (gtktreemodelfilter.c line 1566), my visible function decides "yes, it should be visible" because there is now a child. However, at this point elt->visible is still FALSE!

4. gtk_tree_model_filter_row_has_child_toggled() fails at gtktreemodelfilter.c line 1583 with this output:
(gtk_tree_model_filter_row_has_child_toggled): assertion failed: (elt->visible)

So basically, g_assert(elt->visible) fails in the case where the act of becoming a parent makes the parent visible, and the parent already existed in the GtkTreeModelFilter with elt->visible FALSE.

I did find a workaround, which is to make the child model call gtk_tree_model_row_changed() on the parent just before calling gtk_tree_model_row_has_child_toggled().

I don't know if this is related, but I also noticed that gtk_tree_model_filter_row_inserted() can call gtk_tree_model_row_has_child_toggled() even if the new row should not be visible. That seems wrong to me.
Comment 2 Kristian Rietveld 2009-09-01 09:17:29 UTC
Thanks for the detailed description leading up to the crash.  I am working on an extensive unit test suite for GtkTreeModelFilter model now and I have added this test to it.  Just like you I have found some logic that needs checking in the filter model.  Using the filter model test suite I will resolve this and the other problems that have been reported in Bugzilla soonish.
Comment 3 Kristian Rietveld 2009-09-05 15:26:21 UTC
Fixed on master.