[IGSTK-Users] igstkImageSpatialObject memory management problem

Torleif Sandnes Torleif.Sandnes at sintef.no
Tue Jun 19 03:58:31 EDT 2007


Hi all.

I wrote a volume manager following the statemachine pattern, and when  
I use it, I get a bus error upon exiting the application.
Examining the callstack of the crash, it seems to me that something  
has gone wrong with the reference count of the itk::SmartPointer<>  
used for the igstImageSpatialObject. The VolumeManager class and the  
callstack is attached along with some client code that use the manager.

Any help or pointers would be very much appreciated.

Thanks,

Torleif Sandnes
Sintef Health Research

------------------------------------------------------------------------ 
--
Client code:
// Header file of the client class:

igstkObserverObjectMacro(MRImage,  
igstk::MRImageReader::ImageModifiedEvent, igstk::MRImageSpatialObject)

  igstkObserverMacro(MRImageId, VolumeManager::ImageReadyEvent,  
igstk::EventHelperType::SignedIntType);
igstkObserverObjectMacro(DicomVolume,  
VolumeManager::FoundVolumeEvent, igstk::MRImageSpatialObject);

// Implementation file of the client class:

VolumeManager::Pointer volManager = VolumeManager::instance();
MRImageIdObserver::Pointer mrImageIdObserver = MRImageIdObserver::New();
volManager->AddObserver(VolumeManager::ImageReadyEvent(),  
mrImageIdObserver);

volManager->requestLoadDicomVolume(directoryName);
if(mrImageIdObserver->GotMRImageId())
{
     std::cout << "******* Image loaded\n";
     DicomVolumeObserver::Pointer  dicomVolumeObserver =  
DicomVolumeObserver::New();
     volManager->AddObserver(VolumeManager::FoundVolumeEvent(),  
dicomVolumeObserver);
     volManager->requestGetVolume(mrImageIdObserver->GetMRImageId());
     if(dicomVolumeObserver->GotDicomVolume())
     {
         imageSpatialObject_ = dicomVolumeObserver->GetDicomVolume();
         std::cout << "refcont is " << imageSpatialObject_- 
 >GetReferenceCount() << std::endl;
     }
}


VolumeManager:

class VolumeManager : public igstk::Object
{
public:
     igstkStandardClassBasicTraitsMacro(VolumeManager, igstk::Object);
     igstkNewMacro(Self);
     igstkStateMachineMacro();

     static Pointer instance();

     void requestLoadDicomVolume(std::string path);
     void requestGetVolume(int volumeId);

     igstkLoadedEventMacro(ImageReadyEvent, igstk::IGSTKEvent,  
igstk::EventHelperType::SignedIntType);
     igstkLoadedEventMacro(DicomImageFailedLoading,  
igstk::IGSTKEvent, igstk::EventHelperType::StringType);
     igstkLoadedObjectEventMacro(FoundVolumeEvent, igstk::IGSTKEvent,  
igstk::MRImageSpatialObject);
private:
     VolumeManager();
     ~VolumeManager();
     int addVolume(igstk::SpatialObject::Pointer);
     static Pointer mInstance;
     std::vector<igstk::MRImageSpatialObject::Pointer> mSpatialObjects;

     // States
     igstkDeclareStateMacro(Initial);
     igstkDeclareStateMacro(AttemptingToLoadDicomVolume);
     igstkDeclareStateMacro(DicomVolumeReady);
     // Inputs
     igstkDeclareInputMacro(LoadDicomVolume);
     igstkDeclareInputMacro(DicomVolumeLoadingSuccess);
     igstkDeclareInputMacro(DicomVolumeLoadingFailure);
     igstkDeclareInputMacro(GetDicomVolume);
     igstkDeclareInputMacro(InvalidDicomVolume);

     // Action methods
     void noProcessing();
     void loadImageProcessing();
     void getDicomVolumeProcessing();

     std::string mDicomVolumePath;
     int mVolumeIdToBeRetrieved;
     typedef igstk::DICOMInvalidRequestErrorEvent  
InvalidRequestErrorEvent;
     typedef igstk::DICOMImageReadingErrorEvent ImageReadingErrorEvent;
     igstkEventTransductionMacro(InvalidRequestErrorEvent,  
DicomVolumeLoadingFailureInput);
     igstkEventTransductionMacro(ImageReadingErrorEvent,  
DicomVolumeLoadingFailureInput);

     igstkObserverObjectMacro(MRImage,  
igstk::MRImageReader::ImageModifiedEvent, igstk::MRImageSpatialObject);
};

using std::vector;
using std::string;

VolumeManager::Pointer VolumeManager::mInstance;

VolumeManager::VolumeManager() :
     m_StateMachine(this),
     mVolumeIdToBeRetrieved(-1)
{
     // States
     igstkAddStateMacro(Initial);
     igstkAddStateMacro(AttemptingToLoadDicomVolume);
     igstkAddStateMacro(DicomVolumeReady);

     // Inputs
     igstkAddInputMacro(LoadDicomVolume);
     igstkAddInputMacro(DicomVolumeLoadingSuccess);
     igstkAddInputMacro(DicomVolumeLoadingFailure);
     igstkAddInputMacro(GetDicomVolume);
     igstkAddInputMacro(InvalidDicomVolume);

     // Transitions
     igstkAddTransitionMacro(Initial, LoadDicomVolume,
                             AttemptingToLoadDicomVolume, loadImage);
     igstkAddTransitionMacro(AttemptingToLoadDicomVolume,  
DicomVolumeLoadingSuccess, DicomVolumeReady, no);
     igstkAddTransitionMacro(AttemptingToLoadDicomVolume,  
DicomVolumeLoadingFailure, Initial, no);
     igstkAddTransitionMacro(DicomVolumeReady, GetDicomVolume,  
DicomVolumeReady, getDicomVolume);
     igstkAddTransitionMacro(DicomVolumeReady, InvalidDicomVolume,  
DicomVolumeReady, no);

     // Statemachine
     igstkSetInitialStateMacro(Initial);
     m_StateMachine.SetReadyToRun();
}

VolumeManager::~VolumeManager()
{}

void VolumeManager::requestLoadDicomVolume(string path)
{
     mDicomVolumePath = path;
     m_StateMachine.PushInput(m_LoadDicomVolumeInput);
     m_StateMachine.ProcessInputs();
}

void VolumeManager::requestGetVolume(int volumeId)
{
     if( (volumeId >= 0) && ( mSpatialObjects.size()) )
     {
         mVolumeIdToBeRetrieved = volumeId;
         m_StateMachine.PushInput(m_GetDicomVolumeInput) ;
     }
     else
     {
         m_StateMachine.PushInput(m_InvalidDicomVolumeInput);
     }

     m_StateMachine.ProcessInputs();
}

void VolumeManager::noProcessing()
{}

// Loads a DICOM image and adds it to the internal vector of volumes
void VolumeManager::loadImageProcessing()
{
     std::cout << "loadImageProcessing()\n";
     typedef igstk::MRImageReader ReaderType;
     ReaderType::Pointer imageReader = ReaderType::New();

     MRImageObserver::Pointer imageReadyObserver =  
MRImageObserver::New();
     imageReader->AddObserver(igstk::MRImageReader::ImageModifiedEvent 
(), imageReadyObserver);

     ObserveInvalidRequestErrorEvent(imageReader);
     ObserveImageReadingErrorEvent(imageReader);

//    ReaderType::DirectoryNameType directoryName = mDicomVolumePath;
     imageReader->RequestSetDirectory(mDicomVolumePath);
     imageReader->RequestReadImage();
     imageReader->RequestGetImage();
     if(imageReadyObserver->GotMRImage())
     {
         igstk::MRImageSpatialObject::Pointer  theImage =  
imageReadyObserver->GetMRImage();
         mSpatialObjects.push_back(theImage);

         ImageReadyEvent event;
         event.Set(mSpatialObjects.size() - 1);
         InvokeEvent(event);
         m_StateMachine.PushInput(m_DicomVolumeLoadingSuccessInput);
         m_StateMachine.ProcessInputs();
     }
     else
     {
         m_StateMachine.PushInput(m_DicomVolumeLoadingFailureInput);
         m_StateMachine.ProcessInputs();
     }
}

void VolumeManager::getDicomVolumeProcessing()
{
     FoundVolumeEvent event;
     event.Set(mSpatialObjects.at(mVolumeIdToBeRetrieved));
     InvokeEvent(event);
}

VolumeManager::Pointer VolumeManager::instance()
{
     if(mInstance.IsNull())
     {
         mInstance = VolumeManager::New();
     }
     return mInstance;
}

Call stack:
Thread 0 Crashed:
0   <<00000000>> 	0x00000000 0 + 0
1                                  	0x008fcccf  
vtkGarbageCollectorToObjectBaseFriendship::ReportReferences 
(vtkGarbageCollector*, vtkObjectBase*) + 31
2                                  	0x0016ebbb  
vtkGarbageCollectorImpl::VisitTarjan(vtkObjectBase*) + 629
3                                  	0x0016ed84  
vtkGarbageCollectorImpl::MaybeVisit(vtkObjectBase*) + 174
4                                  	0x0016edf4  
vtkGarbageCollectorImpl::Report(vtkObjectBase*, void*) + 36
5                                  	0x0016f1dd  
vtkGarbageCollectorImpl::Report(vtkObjectBase*, void*, char const*) +  
905
6                                  	0x0016ce0b  
vtkGarbageCollectorReportInternal(vtkGarbageCollector*,  
vtkObjectBase*, void*, char const*) + 45
7                                  	0x007d4cee void  
vtkGarbageCollectorReport<vtkInformation>(vtkGarbageCollector*,  
vtkInformation*&, char const*) + 42
8                                  	0x00089777  
vtkInformationVector::ReportReferences(vtkGarbageCollector*) + 87
9                                  	0x008fcccf  
vtkGarbageCollectorToObjectBaseFriendship::ReportReferences 
(vtkGarbageCollector*, vtkObjectBase*) + 31
10                                 	0x0016ebbb  
vtkGarbageCollectorImpl::VisitTarjan(vtkObjectBase*) + 629
11                                 	0x0016ed84  
vtkGarbageCollectorImpl::MaybeVisit(vtkObjectBase*) + 174
12                                 	0x0016edf4  
vtkGarbageCollectorImpl::Report(vtkObjectBase*, void*) + 36
13                                 	0x0016f1dd  
vtkGarbageCollectorImpl::Report(vtkObjectBase*, void*, char const*) +  
905
14                                 	0x0016ce0b  
vtkGarbageCollectorReportInternal(vtkGarbageCollector*,  
vtkObjectBase*, void*, char const*) + 45
15                                 	0x007d3b7a void  
vtkGarbageCollectorReport<vtkInformationVector>(vtkGarbageCollector*,  
vtkInformationVector*&, char const*) + 42
16                                 	0x0007c76f  
vtkExecutive::ReportReferences(vtkGarbageCollector*) + 161
17                                 	0x008fcccf  
vtkGarbageCollectorToObjectBaseFriendship::ReportReferences 
(vtkGarbageCollector*, vtkObjectBase*) + 31
18                                 	0x0016ebbb  
vtkGarbageCollectorImpl::VisitTarjan(vtkObjectBase*) + 629
19                                 	0x0016ed84  
vtkGarbageCollectorImpl::MaybeVisit(vtkObjectBase*) + 174
20                                 	0x0016edf4  
vtkGarbageCollectorImpl::Report(vtkObjectBase*, void*) + 36
21                                 	0x0016f1dd  
vtkGarbageCollectorImpl::Report(vtkObjectBase*, void*, char const*) +  
905
22                                 	0x0016ce0b  
vtkGarbageCollectorReportInternal(vtkGarbageCollector*,  
vtkObjectBase*, void*, char const*) + 45
23                                 	0x007d2266 void  
vtkGarbageCollectorReport<vtkExecutive>(vtkGarbageCollector*,  
vtkExecutive*&, char const*) + 42
24                                 	0x0007912b  
vtkAlgorithm::ReportReferences(vtkGarbageCollector*) + 61
25                                 	0x008fcccf  
vtkGarbageCollectorToObjectBaseFriendship::ReportReferences 
(vtkGarbageCollector*, vtkObjectBase*) + 31
26                                 	0x0016ebbb  
vtkGarbageCollectorImpl::VisitTarjan(vtkObjectBase*) + 629
27                                 	0x0016ed84  
vtkGarbageCollectorImpl::MaybeVisit(vtkObjectBase*) + 174
28                                 	0x0016f236  
vtkGarbageCollectorImpl::FindComponents(vtkObjectBase*) + 30
29                                 	0x0016f250  
vtkGarbageCollectorImpl::CollectInternal(vtkObjectBase*) + 24
30                                 	0x0016f791  
vtkGarbageCollector::Collect(vtkObjectBase*) + 399
31                                 	0x0008238b  
vtkObjectBase::UnRegisterInternal(vtkObjectBase*, int) + 129
32                                 	0x000976ae  
vtkObject::UnRegisterInternal(vtkObjectBase*, int) + 922
33                                 	0x000779bd  
vtkAlgorithm::UnRegister(vtkObjectBase*) + 39
34                                 	0x00081dea vtkObjectBase::Delete 
() + 32
35                                 	0x008b85c0  
igstk::ImageSpatialObject<unsigned short, (unsigned) 
3>::~ImageSpatialObject [not-in-charge]() + 72  
(igstkImageSpatialObject.txx:106)
36                                 	0x0012d744  
igstk::MRImageSpatialObject::~MRImageSpatialObject [in-charge  
deleting]() + 60 (igstkMRImageSpatialObject.cxx:36)
37                                 	0x00037bcb  
itk::LightObject::UnRegister() const + 83
38                                 	0x0003afd7 itk::Object::UnRegister 
() const + 603
39                                 	0x006c7525  
itk::SmartPointer<igstk::MRImageSpatialObject>::UnRegister() + 37
40                                 	0x006c7539  
itk::SmartPointer<igstk::MRImageSpatialObject>::~SmartPointer [in- 
charge]() + 17
41                                 	0x006c75b3  
MainWindow::DicomVolumeObserver::~DicomVolumeObserver [in-charge  
deleting]() + 43
42                                 	0x00037bcb  
itk::LightObject::UnRegister() const + 83
43                                 	0x0003afd7 itk::Object::UnRegister 
() const + 603
44                                 	0x0074d8f9  
itk::SmartPointer<itk::Command>::UnRegister() + 37
45                                 	0x0074d90d  
itk::SmartPointer<itk::Command>::~SmartPointer [in-charge]() + 17
46                                 	0x0074d9b7  
itk::Observer::~Observer [in-charge deleting]() + 83
47                                 	0x0003b95f  
itk::SubjectImplementation::~SubjectImplementation [in-charge]() + 63
48                                 	0x0003c07b itk::Object::~Object  
[not-in-charge]() + 467
49                                 	0x00060450 igstk::Object::~Object  
[not-in-charge]() + 58 (igstkObject.cxx:36)
50                                 	0x00018071  
VolumeManager::~VolumeManager [in-charge deleting]() + 843
51                                 	0x00037bcb  
itk::LightObject::UnRegister() const + 83
52                                 	0x0003afd7 itk::Object::UnRegister 
() const + 603
53                                 	0x006c86ad  
itk::SmartPointer<VolumeManager>::UnRegister() + 37
54                                 	0x006c86c1  
itk::SmartPointer<VolumeManager>::~SmartPointer [in-charge]() + 17
55                                 	0x0001a0da __tcf_2 + 26
56                                 	0x000052cd cxa_atexit_wrapper + 115
57  libSystem.B.dylib              	0x90010781 __cxa_finalize + 226
58  libSystem.B.dylib              	0x90010688 exit + 24
59                                 	0x00004eba _start + 224
60                                 	0x00004dd9 start + 41




More information about the IGSTK-Users mailing list