[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