Re: Gtk::SpinButton crash




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



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