Re: [sigc] Strange crashes in sigc::trackable on Mac OS X
- From: Michael Ekstrand <mekstran scl ameslab gov>
- To: "Murray Cumming" <murrayc murrayc com>
- Cc: libsigc-list gnome org
- Subject: Re: [sigc] Strange crashes in sigc::trackable on Mac OS X
- Date: Fri, 21 Jul 2006 09:04:31 -0500
On Jul 21, 2006, at 1:11 AM, Murray Cumming wrote:
[snip]
What was happening: a slot was being destroyed twice.
slot_rep::disconnect() was being invoked on an already-deallocated
slot object.
[snip]
This suggests that one of your own objects (which owned a slot) is
being
destroyed twice. Again, valgrind can help with this kind of thing.
OK, I'll give Valgrind a shot sometime here (or at least look in to
dmalloc's facilities for investigating such problems). I've run
Valgrind on it before, but haven't been able to make much sense of
the output. Didn't look at it for very long though. So far dmalloc
seems to make much more sense to me than valgrind.
However, in my previous e-mail, I did lay out what it seemed to me
was happening in the code from my investigation with dmalloc and GDB
- a signal being destroyed during a nofity callback of one of its
slots. And if one of my own objects was being destroyed twice,
dmalloc should have made it blow up earlier than this.
I since have done a more thorough investigation of (and more thinking
on) the code paths involved, including digging around in the libsigc+
+ sources for a while this morning, and suspicions seem to be
confirmed (and clarified - I had some details wrong) - it does in
fact seem that the slot is being disconnected from both ends in a
problematic manner. In slot_rep::notify, the following sequence
happens:
* Clear call (invalidate slot)
* Destroy slot
* Disconnect slot (noted that it might lead to the deletion of self_)
Now, the destroy call, it seems, destroys the functor. In this case,
the functor is a sigc::bind instance maintaining a reference - the
last reference - to the object containing the signal to which this
slot is connected. So destroying the functor releases the
references, which deletes the object, which deletes signal, and the
signal deletes its list of slots. Our slot is in that list, and thus
gets deleted. The signal is thus already deleted before it gets to
the disconnect() call. So in slot_rep::disconnect(), we see data,
but the object has been deleted (a fact made evident by dmalloc's
free blanking).
My previous email said the slot was being destroyed twice - I now
believe that is incorrect; it is merely being deleted in the destroy
() call in slot_rep::notify, and notify doesn't expect this.
I've tried to duplicate this scenario in a simple test case, but thus
far to no avail.
The question in my mind, though: Is it a problem in my application
that I'm even allowing such a scenario to exist (where the signal is
deleted during the slot's destroy() call), or should libsigc++ deal
gracefully with this and my problem is therefore a bug in libsigc++?
- Michael
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]