[IGSTK-Users] igstkImageSpatialObject memory management problem

Luis Ibanez luis.ibanez at kitware.com
Tue Jun 19 13:47:44 EDT 2007


Hi Torleif,


A couple of questions:


1) Why are you using a Singleton for the volume Manager ?


2) Are you creating a shared library with this class ?


3) Can you please send the actual source files and
    test files ? something we could compile and run
    in order to reproduce the problem.

    In the code snippets that you sent we can't find
    the declaration of "imageSpatialObject_"... for
    example



If you are creating a shared library, and instantiating
the Singleton in that library, that will explain the
memory issue. Static variables declared in shared
libraries are initialized at unpredictable times.


-------


BTW:  Please don't do:


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


This is equivalent to opening the namespace for these
symbols. Instead of doing this, you should always use
the std:: namespace specifier.



Please let us know about the questions above,


    Thanks


      Luis


---------------------
Torleif Sandnes wrote:
> 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
> 
> _______________________________________________
> IGSTK-Users mailing list
> IGSTK-Users at public.kitware.com
> http://public.kitware.com/cgi-bin/mailman/listinfo/igstk-users
> 


More information about the IGSTK-Users mailing list