Page MenuHomePhabricator

Possible crash caused by unremoved observer in mitkLevelWindowManager
Closed, ResolvedPublic

Description

The LevelWindowManager class contains two maps of type

typedef std::map<unsigned long, BaseProperty::Pointer> ObserverToPropertyMap;

The key parameter (unsigned long) is obtain by calling

it->Value()->GetProperty("...")->AddObserver(...)

where "it" is an iterator of type

mitk::DataStorage::SetOfObjects::ConstIterator

If the SetOfObjects contains more than one element, multiple observers with the same key will be added to the map, as in mitkLevelWindowManager.cpp:288

for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
     it != all->End();
     ++it)
{
  if (it->Value().IsNull())
    continue;
  /* register listener for changes in layer property */
  itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command2 = itk::ReceptorMemberCommand<LevelWindowManager>::New();
  command2->SetCallbackFunction(this, &LevelWindowManager::Update);
  m_PropObserverToNode2[it->Value()->GetProperty("layer")->AddObserver( itk::ModifiedEvent(), command2)] = it->Value()->GetProperty("layer");
}

The call to the RemoveObserver() method will only remove one and only one observer even if multiple observers have been added

for (ObserverToPropertyMap::iterator iter = m_PropObserverToNode2.begin();
     iter != m_PropObserverToNode2.end();
     ++iter)
{
  (*iter).second->RemoveObserver((*iter).first);
}

Observers might still be registered in the system even after LevelWindowManager object is deleted. Crash will occur if the observed event is emitted and the callback method (here, Update()) is called without existing object.

A fix is to change ObserverToPropertyMap by

typedef std::pair<unsigned long, DataNode::Pointer> PropDataPair;
typedef std::map<PropDataPair, BaseProperty::Pointer> ObserverToPropertyMap;

to be sure to have a unique observer identifier for each objects of the SetOfObjects.

I will submit a patch shortly.

Event Timeline

Patch has been submitted on Github.

Hi Felix,

thanks for the fix, we will have someone look at it soon.

Changed Target Milestone to upcoming release

To test this bug we need a test of the class mitkLevelWindowManager. This test is deactivated at the moment (see T13889). Fix this bug first.

New remote branch pushed: bug-13499-UnremovedObserverInLevelWindowManager

Is it possible for me to contribute directly to the new branch (if needed)? Branches don't seem synced on the Github repository.

We tested the changes proposed by Felix (bug-13499-UnremovedObserverInLevelWindowManager) with the test of this class in branch bug-13889-FixMitkLevelWindowManagerTest.

It seems that the fix is not complete because the test still fails. Maybe it is best to wait until the test is finished and then continue working on this bug.

Updating target milestone to upcoming release

[73d7b5]: Merge branch 'bug-13499-UnremovedObserverInLevelWindowManager'

Merged commits:

2013-02-13 15:34:05 Alfred Franz [1199d7]
minor change: removed parameter which is given by default anyway


2013-02-13 15:33:20 Alfred Franz [d0119f]
DOC: Added doxygen commands for most methods


2013-02-13 15:13:40 Alfred Franz [2621d6]
fixed a bug: Initialized the LevelWindowManager also in the AddNode method


2013-02-13 14:09:40 Alfred Franz [75a329]
added for loop (forgotten in last commit)


2013-02-06 17:05:42 Alfred Franz [a4d06a]
fixed a bug with an iterator: replaced by for loop for the moment


2013-02-06 16:45:30 Alfred Franz [95cc44]
removed debug output


2013-02-06 16:44:11 Alfred Franz [83077b]
added a check if the removed node is relevant


2013-02-06 15:21:58 Alfred Franz [cdb09d]
removed absolute path from test data


2013-02-06 14:41:56 Alfred Franz [92bc74]
added another internal method for better structure, added documentation


2013-01-23 16:25:56 Alfred Franz [040b5d]
restructured code: (1) added internal help methods for better code structure (2) renamed method (3) fixed bug when removing nodes


2013-01-23 16:20:58 Alfred Franz [dea639]
finished restructuring of test, extended method for testing observers


2013-01-23 14:35:14 Alfred Franz [b56621]
Merge branch 'bug-13889-FixMitkLevelWindowManagerTest' into bug-13499-UnremovedObserverInLevelWindowManager


2013-01-23 14:33:37 Alfred Franz [fb80bd]
DOC: added documentation


2013-01-23 14:25:06 Alfred Franz [efa6ee]
further adaption of test code to mitk testing macros


2012-12-07 15:33:43 Alfred Franz [9c997c]
temporary added output of number of observers


2012-12-05 17:54:59 Alfred Franz [7e4bcc]
Merge branch 'bug-13889-FixMitkLevelWindowManagerTest' into bug-13499-UnremovedObserverInLevelWindowManager


2012-12-05 17:54:17 Alfred Franz [151177]
integrated code from Felix C. Morency from github pull request (see T13499)


2012-12-05 17:31:06 Alfred Franz [49c398]
added method GetNumberOfObservers


2012-12-05 17:30:41 Alfred Franz [1cb616]
added a test for removing of observers


2012-12-05 16:06:50 Alfred Franz [4bbb96]
restructured test


2012-12-05 16:05:08 Alfred Franz [58e2cc]
comment code in again


2012-12-05 15:37:27 Alfred Franz [d566eb]
converted exceptions to MITK exceptions, added documentation


2012-12-05 15:36:51 Alfred Franz [e1dfe7]
started conversion of old style test to MITK testing macros


2012-12-05 15:34:35 Alfred Franz [5b5880]
activated test again