All,
I've been watching a number of crashes in the code that all have to do with
Event methods being called with 'this' == NULL (0x00000000). I think I might
have a lead on the issue.
Note the code below in CHistory.cpp around line 53:
CHistory::~CHistory() {
//delete _pHistory;
}
void CHistory::initPresentationThreadSafe() {
_pHistory = PFactory::getFactory().createPresentationHistory(*this);
_history.historyLoadedEvent +=
boost::bind(&CHistory::historyLoadedEventHandler, this, _1);
_history.mementoAddedEvent +=
boost::bind(&CHistory::historyMementoAddedEventHandler, this, _1, _2);
_history.mementoUpdatedEvent +=
boost::bind(&CHistory::historyMementoUpdatedEventHandler, this, _1, _2);
_history.mementoRemovedEvent +=
boost::bind(&CHistory::historyMementoRemovedEventHandler, this, _1, _2);
_history.unseenMissedCallsChangedEvent +=
boost::bind(&CHistory::unseenMissedCallsChangedEventhandler, this, _1, _2);
}
When CHistory is destroyed (on exit or whenever happens), these bindings are
not removed since _history remains (don't know who deletes). boost::bind
only creates a function pointer which is now called with this == NULL after
a delete (if we are lucky). In reality, 'this' should be undefined (I may
misunderstand C++ on this), which would cause even stranger behavior.
Solutions:
1) Expect every EventHandler function to return if 'this' is NULL:
if (this == NULL)
return;
2) remove the bindings on destroy if the linked object is not destroyed:
Option 1:
CHistory::~CHistory() {
//delete _pHistory;
_history.historyLoadedEvent -=
boost::bind(&CHistory::historyLoadedEventHandler, this, _1);
_history.mementoAddedEvent -=
boost::bind(&CHistory::historyMementoAddedEventHandler, this, _1, _2);
_history.mementoUpdatedEvent -=
boost::bind(&CHistory::historyMementoUpdatedEventHandler, this, _1, _2);
_history.mementoRemovedEvent -=
boost::bind(&CHistory::historyMementoRemovedEventHandler, this, _1, _2);
_history.unseenMissedCallsChangedEvent -=
boost::bind(&CHistory::unseenMissedCallsChangedEventhandler, this, _1, _2);
}
Option 1:
CHistory::~CHistory() {
//delete _pHistory;
_history.historyLoadedEvent -=
boost::bind(&CHistory::historyLoadedEventHandler, this, _1);
_history.mementoAddedEvent -=
boost::bind(&CHistory::historyMementoAddedEventHandler, this, _1, _2);
_history.mementoUpdatedEvent -=
boost::bind(&CHistory::historyMementoUpdatedEventHandler, this, _1, _2);
_history.mementoRemovedEvent -=
boost::bind(&CHistory::historyMementoRemovedEventHandler, this, _1, _2);
_history.unseenMissedCallsChangedEvent -=
boost::bind(&CHistory::unseenMissedCallsChangedEventhandler, this, _1, _2);
}
No idea if this will work, as I'm guessing 'bind' creates a new 'object' so
the pointers wont match
Option 2:
Store the results of boost::bind locally and then -= them on destroy
Option 3:
Add a method to Event.h which removes all events targeted to a particular
object, and pass it 'this'. However this doesn't seem compatible with how
'bind' works.
Finally, I'm not sure what is being passed is a 'Slot' or an Event (I was
looking at operator-=() in Event.h) so that might present problems as well.
Hope this analysis helps,
-Lukas
Lukas Oberhuber
_______________________________________________
Wengophone-devel mailing list
[email protected]
http://dev.openwengo.com/mailman/listinfo/wengophone-devel