Crash on exit with a static variable containing DcmDataset's

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
Quim
Posts: 1
Joined: Thu, 2008-04-03, 17:27

Crash on exit with a static variable containing DcmDataset's

#1 Post by Quim »

Hello all,

My application crashes on exit with an error "R6025 - pure virtual function call". I'm working with MSVC 2008 and dcmtk 3.5.4 build with /MDd option. I've been searching for a solution and I've found this viewtopic.php?t=1119 . After following Marco's advice I've obtained the same result than before.

I've striped down the problem to a testing program that produces the same result. The backtrace at the error is this:

Code: Select all

	msvcr90d.dll!_NMSG_WRITE(int rterrnum=25)  Line 198	C
 	msvcr90d.dll!_purecall()  Line 54 + 0x7 bytes	C
 	SimpleView.exe!OFCondition::~OFCondition()  Line 350 + 0x13 bytes	C++
 	SimpleView.exe!DcmObject::~DcmObject()  Line 86 + 0xb bytes	C++
 	SimpleView.exe!DcmElement::~DcmElement()  Line 153 + 0xf bytes	C++
 	SimpleView.exe!DcmUnsignedLong::~DcmUnsignedLong()  Line 62 + 0x8 bytes	C++
 	SimpleView.exe!DcmUnsignedLong::`scalar deleting destructor'()  + 0x16 bytes	C++
 	SimpleView.exe!DcmItem::~DcmItem()  Line 137 + 0x22 bytes	C++
 	SimpleView.exe!DcmDataset::~DcmDataset()  Line 76 + 0x8 bytes	C++
 	SimpleView.exe!DcmDataset::`scalar deleting destructor'()  + 0x16 bytes	C++
 	SimpleView.exe!Cache::~Cache()  Line 14 + 0x27 bytes	C++
 	SimpleView.exe!`dynamic atexit destructor for 'Foo::m_cache''()  + 0xd bytes	C++
 	msvcr90d.dll!doexit(int code=0, int quick=0, int retcaller=0)  Line 591	C
 	msvcr90d.dll!exit(int code=0)  Line 412 + 0xd bytes	C
 	SimpleView.exe!__tmainCRTStartup()  Line 595	C
 	SimpleView.exe!mainCRTStartup()  Line 399	C
This error is produced by this test program:

Code: Select all

#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcsequen.h>

#include <list>
#include <iostream>

class Cache
{
public:
    ~Cache()
    {
        for(std::list<DcmDataset*>::iterator i = m_list.begin(); i != m_list.end(); i++)
        {
            delete *i;
        }
    }

    void insert(DcmDataset* dataset)
    {
        m_list.push_front(dataset);
    }

private:
    std::list<DcmDataset*> m_list;
};

class Foo
{
public:
    void causeError(char file[]);
private:
    static Cache m_cache;
};

Cache Foo::m_cache;


void Foo::causeError(char file[])
{
    DcmFileFormat dicomFile;
    DcmDataset *dataset;
    OFCondition status = dicomFile.loadFile(file);
    if( status.good() )
    {
        dataset = dynamic_cast<DcmDataset*>( dicomFile.getAndRemoveDataset()->clone() );
        m_cache.insert(dataset);
    }
}

int main( int argc, char** argv )
{
    if (argc == 2)
    {
        Foo a;
        a.causeError(argv[1]);
    }
    else
    {
        std::cout << "You need to pass as parameter a dicom file" << std::endl;
    }
}
In the test main if you remove the "static" from m_cache declaration of Foo class the program exits normally, without the segfault.

Or there's a problem with the order of deletion of static data or (surely the winner option) I'm blind to the error I'm making :)

Any idea?

thanks

PS: On linux the original program doesn't have this problem

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1461
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#2 Post by Marco Eichelberg »

The problem is the undefined destruction order of global objects. Any DcmDataset pointer will contain OFCondition flags which typically point to a global object (the most important being ECC_Normal declared in ofstd/libsrc/ofconf.cc). Your static object Cache Foo::m_cache is probably destructed after ECC_Normal, thus causing the destructor of some OFCondition object to cause this error. You could either implement a Cache::cleanup() method that deletes the cache content and call this from main() prior to application termination, or you could refrain from using a static object in class Foo (e.g., by using a static pointer instead and construction the object on the heap).

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 1 guest