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

Reply via email to