Re: [sigc] Strange crashes in sigc::trackable on Mac OS X



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]