Closed daym closed 3 years ago
Uhm, what exactly are you trying to achieve here? The tree-store:append!
call appears to be storing a <GClosure>
with value NULL
, which in my opinion can not end well.
In my opinion, bindings should not corrupt the heap.
I don't store anything anywhere here, explicitly.
This is completely normal stuff.
In general, for all the issues I open here:
(1) it actually happens to me in a normal program I wrote, without trying to make it happen (2) I find a minimal reproducer (I hope I got it to corrupt in general--otherwise it's gonna be difficult to find) (3) I write a similar program in C to compare
So I did here. This totally works, and the output is (nil)
:
#include <gtk/gtk.h>
int main(int argc, char* argv[]) {
GtkTreeIter iter;
void* p = NULL;
gtk_init(&argc, &argv);
GtkTreeStore* store = gtk_tree_store_new(1, G_TYPE_CLOSURE);
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &p, -1);
g_warning("%p", p);
return 0;
}
Now, I'm reading the Gtk source code...
In this case, I use G_TYPE_CLOSURE
as a workaround in order to store a Guix <package>
record into a GtkTreeStore
row. When I read a Guix manifest, I do not have the package yet (only name, version, output name and provenance)--the respective package is lazy-loaded on demand.
Hmm, my results inside Guix environment are slightly different, but as we know from #96, we can't trust those. I've pushed a commit with a test, that has been inspired by yours, perhaps that solves it or perhaps it breaks the CI.
Thanks.
For reference, this is in gtktreedatalist.c
:
void
_gtk_tree_data_list_free (GtkTreeDataList *list,
GType *column_headers)
{
GtkTreeDataList *tmp, *next;
gint i = 0;
tmp = list;
while (tmp)
{
next = tmp->next;
if (g_type_is_a (column_headers [i], G_TYPE_STRING))
g_free ((gchar *) tmp->data.v_pointer);
else if (g_type_is_a (column_headers [i], G_TYPE_OBJECT) && tmp->data.v_pointer != NULL)
g_object_unref (tmp->data.v_pointer);
else if (g_type_is_a (column_headers [i], G_TYPE_BOXED) && tmp->data.v_pointer != NULL)
g_boxed_free (column_headers [i], (gpointer) tmp->data.v_pointer);
else if (g_type_is_a (column_headers [i], G_TYPE_VARIANT) && tmp->data.v_pointer != NULL)
g_variant_unref ((gpointer) tmp->data.v_pointer);
g_slice_free (GtkTreeDataList, tmp);
i++;
tmp = next;
}
}
That suggests that g_boxed_free
, g_object_unref
, g_variant_unref
don't check for NULL
.
Also, the _gtk_tree_data_list_alloc
(in the same file) uses g_slice_new0
to allocate the thing. That implies that the initial value of v_pointer
will be NULL
.
Fix pushed. For the record, your code contained a fair number of typos, so here is the updated and fixed test case:
Message:
Something like g_boxed_free NULL
then corrupts heap.
Test: