Re: Problem with global destruction




On Mar 29, 2007, at 2:03 PM, Ari Jolma wrote:

I'm getting back to this issue, since I finally got a good gdb backtrace
and Glib NOISY log from the bug(?):

Below are three logs, the first and third are from gdb, they show that
the SegFault may happen at least in g_signal_emit_valist () and
g_signal_has_handler_pending (). The 2nd log shows that the segfault
seems to happen in this case when Gtk2::Window has been destroyed and
Gtk2::SpinButton is being destroyed (in another case  the segfault
happens when Gtk2::ComboBox is being destroyed). The SpinButton and
ComboBox are both widgets in a dialog that is created with Gtk2::GladeXML.

Hrm, you didn't mention GladeXML before. Do you have a global reference to the GladeXML object anywhere?


Crashes in global destruction are usually the result of reference leaks leading to memory corruption. A GObject will be kept alive as long as there is a perl reference to it. An explicit destroy usually cures this, but if your code stores global references or complicated reference cycles, you can create nasty situations.

Try making sure that:

1. You destroy stuff before exit (either implicit or explicit). Most notably, if destroying your main window is not the trigger that stops the main loop, then make sure you destroy the main window before execution stops. 2. You break reference cycles as soon as possible, usually in a "destroy" signal. 3. Be very careful with trapping widgets references in closures. It's normally alright, but in certain cases can cause very well- hidden reference cycles.



#10 0x617df752 in libgtk-win32-2!gtk_container_remove ()
   from d:\PROGRA~1\COMMON~1\GTK\2.0\bin\libgtk-win32-2.0-0.dll
#11 0x619dcc99 in libgtk-win32-2!gtk_widget_hide_on_delete ()
   from d:\PROGRA~1\COMMON~1\GTK\2.0\bin\libgtk-win32-2.0-0.dll
#12 0x63a46eef in libgobject-2!g_object_unref ()
   from d:\PROGRA~1\COMMON~1\GTK\2.0\bin\libgobject-2.0-0.dll
#13 0x69090378 in gperl_object_check_type ()
   from D:\perl\site\lib\auto\Glib\Glib.dll

That sequence is somewhat suspicious. Hide_on_delete() calling remove () instead of hide()? check_type calling unref? Unref calling hide_on_delete()?


#25 0x10039175 in perl_destruct () from D:\Perl\bin\perl58.dll
#26 0x100cdb20 in perl58!RunPerl () from D:\Perl\bin\perl58.dll

Indeed, global destruction.


DESTROY< (34663f8)[2] => Gtk2::HBox (32187e0)[1], <DATA> line 3699.
DESTROY> (34663f8) done
DESTROY< (34663a8)[2] => Gtk2::VBox (32187e0)[1], <DATA> line 3699.
DESTROY> (34663a8) done
DESTROY< (346b020)[5] => Gtk2::Window (321854c)[1], <DATA> line 3699.
DESTROY> (346b020) done
DESTROY< (345f4f8)[1] => Gtk2::SpinButton (90fc94)[1], <DATA> line 3699
during global destruction.

The first hex number in each pair is the C object's address, and the second is the perl object's address. In the square brackets we have their respective reference counts.

I'm no expert on how the heap works on windows, but i find it suspicious that the first three objects are at around 0x3400000 & 0x3200000, but the one on which we crash is in a wholly different part of memory, at 0x3400000 & 0x900000. Notice that the C objects are all around 0x3400000 and those are not far from the first three perl objects at 0x3200000. The C object must be valid at this point, because we were able to ask its type, and look up its type in the bindings' GType-to-package-name map.

However, the last object's perl wrapper is an order of magnitude lower in memory. Normally i'd say that is a likely indicator of badness, but we can still dereference that wonky pointer to get the perl reference count without crashing, so perhaps i'm just imagining things.


Is the SpinButton supposed to be a child of the Window?


Where is the corresponding "gperl_new_object" message for the address of the offending SpinButton? If none exists, then we are looking at a garbage pointer.


And, finally, are you using threads? If so, are you using Glib::set_threadsafe()?


--
It's all very complicated and would take a scientist to explain it.
  -- MST3K





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