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
_______________________________________________
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list