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

Reply via email to