Re: action->get_proxies during connect-proxy emit



Kevin Ryde wrote:
Test case and what I did about it below.  get_proxies isn't a
constructor, so if I'm not mistaken its object returns shouldn't be
subject to ref_sink.

That appears do be due to GtkAction not holding a real ref on the proxies but just a weak ref. When connect_proxy in gtkaction.c calls the connect-proxy signal, the proxies weren't added to any container yet and are thus still floating. So gtk_action_get_proxies ends up handing out objects with a floating reference. When gtk2perl_new_gtkobject sees those, it sinks them and thus assumes ownership of the floating ref. When the signal callback returns, the SV wrappers for the proxies go out of scope and that causes destruction of the proxies. Later, some code in gtk+ tries to use the destroyed proxies and things go wrong.

I'm not yet sure who's at fault here: gtk_action_get_proxies for handing out objects that are potentially floating, or us for assuming we can sink any floating objects returned by gtk_action_get_proxies. This and the hard code freeze we're in make me think we should punt on this issue until after the stable releases later today.

But I don't know if this is enough.  In particular I turned on NOISY in
GtkObject.xs and it got a segv ... but perhaps that's something else.

That's something else, yes. The debug code in gtk2perl_new_gtkobject segfaults on NULL objects. The attached patch fixes this for me. Will commit when the code freeze is over.

--
-Torsten
Index: xs/GtkObject.xs
===================================================================
RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/xs/GtkObject.xs,v
retrieving revision 1.17
diff -u -d -p -r1.17 GtkObject.xs
--- xs/GtkObject.xs     16 Jan 2006 22:28:25 -0000      1.17
+++ xs/GtkObject.xs     20 Sep 2008 12:31:55 -0000
@@ -50,12 +50,16 @@ SV *
 gtk2perl_new_gtkobject (GtkObject * object)
 {
 #ifdef NOISY
-       warn ("gtk2perl_new_gtkobject (%s(%p)[%d])\n",
-             G_OBJECT_TYPE_NAME (object),
-             object,
-             G_OBJECT (object)->ref_count);
-       g_signal_connect (object, "destroy", G_CALLBACK (destroy_notify), NULL);
-       g_object_weak_ref (object, weak_ref, NULL);
+       if (object) {
+               warn ("gtk2perl_new_gtkobject (%s(%p)[%d])\n",
+                     G_OBJECT_TYPE_NAME (object),
+                     object,
+                     G_OBJECT (object)->ref_count);
+               g_signal_connect (object, "destroy", G_CALLBACK (destroy_notify), NULL);
+               g_object_weak_ref (G_OBJECT (object), weak_ref, NULL);
+       } else {
+               warn ("gtk2perl_new_gtkobject (NULL)\n");
+       }
 #endif
        /* always sink the object.  if it's not floating, then nothing
         * happens and we get a ref.  if it is floating, then the


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