[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