2013-11-29 13:15, John Emmas skrev:
On 28/11/2013 11:33, John Emmas
wrote:
Thanks
Kjell, I'm busy with another project today but first thing
tomorrow, I'll step through the destruction process and see if
my function sequence matches yours.
Today I've been looking into the 2nd stage of Kjell's destruction
process, namely:-
On 28/11/2013 09:54, Kjell Ahlstedt
wrote:
delete some_spin_button;
Gtk::Object::~Object() calls
Gtk::Object::_destroy_c_instance(), which calls
g_object_unref().
The call to g_object_unref() removes the last
reference to GtkSpinButton.
When the last reference to GtkSpinButton is removed, it also
removes its reference to GtkAdjustment. Both the GtkAdjustment
and GtkSpinButton objects are finalized.
That finalization process (for the GtkAdjustment) is where the
crash occurs. Remember from yesterday that we'd deleted
'some_adjuster'. This deleted the C++ object although it left the
underlying 'C' object intact. But when we reach the stage of
finalizing the GtkAdjustment, it appears to try to access that
deleted C++ object. Here's the sequence (in abbreviated form
because it's really very convoluted):-
1) SpinButton::~SpinButton()
2) Object::destroy_()
3) Object::_destroy_c_instance()
4) gtk_spin_button_finalize() - which calls:-
gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON
(object), NULL);
5) gtk_spin_button_set_adjustment() calls 'g_object_unref
(spin_button->adjustment)'
6) g_object_unref() calls 'object->finalize (object)' (where
'object' is the underlying 'C' GtkAdjustment)
7) The above call to 'finalize()' ends up calling
g_object_finalize() (still for the underlying 'C' GtkAdjustment)
8) The call to g_object_finalize() calls g_datalist_clear().
Note this line:-
data->data[i].destroy (data->data[i].data);
9) The above line ends up calling
'ObjectBase::destroy_notify_callback(void* data)'
at this point I'm not entirely sure what kind of object 'data'
refers to. However, the above function casts it to ObjectBase*
and at that point, MSVC's debugger shows it as a deleted object
(0xfeeefeee pattern). From its memory address I'd guess that it's
one of the base classes for the Gtk::Adjustment that got deleted a
long time ago (though that's just an intuitive guess because the
two addresses are always VERY close to each other). Whatever it
is, it looks like it got deleted when GtK::Adjustment got
deleted. A few lines further down we try to call its
'destroy_notify()' member and that's where the crash occurs.
When 'ObjectBase::destroy_notify_callback()' casts the parameter
to ObjectBase* is there any way to verify if the pointer is
pointing to a valid object? That seems to be the problem AFAICT.
John
The problem is that step 9 occurs, i.e. that
Glib::ObjectBase::destroy_notify_callback_() is called when the
GtkAdjustment is finalized. It should not be called, because of the
call to g_object_steal_qdata() when the Gtk::Adjustment was deleted.
It would be fine if you could try to find out what goes wrong when
g_object_steal_qdata() is called. Why isn't the GQuark removed from
the list of the GtkAdjustment's quarks?
Kjell
|