Offis dcmtk-3.6.1_20160216: Memory Leaks

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
fgigante
Posts: 2
Joined: Wed, 2016-03-02, 16:23

Offis dcmtk-3.6.1_20160216: Memory Leaks

#1 Post by fgigante »

Offis version: dcmtk-3.6.1_20160216
Memory leaks detected by Visual Studio 2013.

Memory leaks detected every time a Document SR Tree is read from inside a thread.

For example it's possible to check the memory leaks in the dumpsr utility.
The original utility (without thread) doesn't have memory leaks.
If I call the main from a thread I have memory leaks.

If I comment the following code in the dumpsr I don't have memory leaks:
result = dsrdoc->read(*dfile->getDataset(), readFlags);

This is the link to download the modified code "dsrdump.zip" to detect the memory leaks by Visual Studio 2013.
https://drive.google.com/open?id=0B0cqz ... S04SmV1bXM

I put the entire code under a thread because it's the only way to see the memory leaks... if I run the code without calling the SR reading functions from a thread I cannot see the memory leaks.

At the bottom of this code see the Visual studio 2013 output "dsrdump_memory_leaks" when you can see the memory leaks log. If I call the same code without the thread, I don't have memory leaks. The output without memory leaks is in this post with the header "dsrdump_NO_memory_leaks"

Code without memory leaks, using only the main thread (see the attached output "dsrdump_memory_leaks.txt"):

ThreadTest(argc, argv);
//std::thread first(ThreadTest, argc, argv);
//first.join();


Code with memory leaks, using a secondary thread call (see the attached output "dsrdump_NO_memory_leaks.txt"):

//ThreadTest(argc, argv);
std::thread first(ThreadTest, argc, argv);
first.join();

I hope you could replicate this issue. I noticed this problem because Visual Studio originally gave me the memory leaks also in my main application, where I read the SR document by a thread. Then I found I could replicate this memory leaks directly on a code written for one of the application embedded into the dmck snapshot!
Also in my main application, if I call the SR reading from the main thread, I cannot have memory leaks.
My main application and dsdump have the same behaviour: memory leaks detected if I call SR reading procedure from within a secondary thread.

=================
"dsrdump_memory_leaks"
=================
The thread 0x5820 has exited with code 0 (0x0).
The thread 0x9078 has exited with code 0 (0x0).
The thread 0x8fb0 has exited with code 0 (0x0).
The thread 0x9d04 has exited with code 0 (0x0).
Detected memory leaks!
Dumping objects ->
{18597} normal block at 0x007E1470, 206 bytes long.
Data: <class OFConditio> 63 6C 61 73 73 20 4F 46 43 6F 6E 64 69 74 69 6F
{18594} normal block at 0x007DFC38, 19 bytes long.
Data: <dcmtk.apps.dsrdu> 64 63 6D 74 6B 2E 61 70 70 73 2E 64 73 72 64 75
{18586} normal block at 0x007D2818, 64 bytes long.
Data: <dsrdump: error (> 64 73 72 64 75 6D 70 3A 20 65 72 72 6F 72 20 28
{18578} normal block at 0x007E1408, 40 bytes long.
Data: <D:\Offis\dcmtk\d> 44 3A 5C 4F 66 66 69 73 5C 64 63 6D 74 6B 5C 64
{17631} normal block at 0x007DEF50, 97 bytes long.
Data: < rdump: error (> 0A 00 72 64 75 6D 70 3A 20 65 72 72 6F 72 20 28
{17623} normal block at 0x007DF910, 97 bytes long.
Data: <dsrdump: error (> 64 73 72 64 75 6D 70 3A 20 65 72 72 6F 72 20 28
{16885} normal block at 0x007DEA00, 522 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{16882} normal block at 0x007DE940, 2 bytes long.
Data: < > 00 00
{16881} normal block at 0x007DE900, 2 bytes long.
Data: < > 00 00
{16880} normal block at 0x007DE8B0, 16 bytes long.
Data: < 2e } } > D0 32 65 01 B0 E8 7D 00 B0 E8 7D 00 01 CD CD CD
{16879} normal block at 0x007DE870, 2 bytes long.
Data: < > 00 00
{16876} normal block at 0x007DE7B0, 2 bytes long.
Data: < > 00 00
{16874} normal block at 0x007DE728, 8 bytes long.
Data: < } > EC CC 7D 00 00 00 00 00
{16873} normal block at 0x007DE6E8, 2 bytes long.
Data: < > 00 00
{16870} normal block at 0x007DE620, 11 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD
{16869} normal block at 0x007DE5E0, 2 bytes long.
Data: < > 00 00
{16868} normal block at 0x007DE5A0, 2 bytes long.
Data: < > 00 00
{16867} normal block at 0x007DE560, 2 bytes long.
Data: < > 00 00
{16866} normal block at 0x007DE520, 2 bytes long.
Data: < > 00 00
{16865} normal block at 0x007DE4E0, 2 bytes long.
Data: < > 00 00
{16864} normal block at 0x007DE4A0, 2 bytes long.
Data: < > 00 00
{16863} normal block at 0x007DE460, 2 bytes long.
Data: < > 00 00
{16862} normal block at 0x007DE420, 2 bytes long.
Data: < > 00 00
{16861} normal block at 0x007DE3D0, 16 bytes long.
Data: < 2e } } > D0 32 65 01 D0 E3 7D 00 D0 E3 7D 00 01 CD CD CD
{16860} normal block at 0x007DE390, 2 bytes long.
Data: < > 00 00
{16859} normal block at 0x007DE350, 2 bytes long.
Data: < > 00 00
{16858} normal block at 0x007DE310, 2 bytes long.
Data: < > 00 00
{16857} normal block at 0x007DE2D0, 2 bytes long.
Data: < > 00 00
{16856} normal block at 0x007DE290, 2 bytes long.
Data: < > 00 00
{16855} normal block at 0x007DE250, 2 bytes long.
Data: < > 00 00
{16854} normal block at 0x007DE210, 2 bytes long.
Data: < > 00 00
{16853} normal block at 0x007DE1D0, 2 bytes long.
Data: < > 00 00
{16852} normal block at 0x007DE190, 2 bytes long.
Data: < > 00 00
{16851} normal block at 0x007DE150, 2 bytes long.
Data: < > 00 00
{16850} normal block at 0x007DE110, 2 bytes long.
Data: < > 00 00
{16849} normal block at 0x007DE0D0, 2 bytes long.
Data: < > 00 00
{16848} normal block at 0x007DE090, 2 bytes long.
Data: < > 00 00
{16847} normal block at 0x007DE050, 2 bytes long.
Data: < > 00 00
{16846} normal block at 0x007DDED8, 2 bytes long.
Data: < > 00 00
{16845} normal block at 0x007DDE98, 2 bytes long.
Data: < > 00 00
{16844} normal block at 0x007DDE58, 2 bytes long.
Data: < > 00 00
{16843} normal block at 0x007DDE18, 2 bytes long.
Data: < > 00 00
{16842} normal block at 0x007DDDD8, 2 bytes long.
Data: < > 00 00
{16841} normal block at 0x007DDD98, 2 bytes long.
Data: < > 00 00
{16840} normal block at 0x007DC198, 2 bytes long.
Data: < > 00 00
{16839} normal block at 0x007DC158, 2 bytes long.
Data: < > 00 00
{16838} normal block at 0x007DDC50, 268 bytes long.
Data: < X } > 0B 00 00 00 58 C1 7D 00 00 00 00 00 01 00 00 00
{16833} normal block at 0x007DCA90, 808 bytes long.
Data: < d d (} (} > F0 F1 64 01 AC F1 64 01 18 28 7D 00 18 28 7D 00
Object dump complete.
The program '[5572] dsrdump.exe' has exited with code 0 (0x0).===


====================
"dsrdump_NO_memory_leaks"
====================
The thread 0x9228 has exited with code 0 (0x0).
The thread 0x5364 has exited with code 0 (0x0).
The program '[38172] dsrdump.exe' has exited with code 0 (0x0).

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: Offis dcmtk-3.6.1_20160216: Memory Leaks

#2 Post by J. Riesmeier »

Could you enable the output of filename and code line in the "memory leak" output? Otherwise I don't know where I have to look at...

fgigante
Posts: 2
Joined: Wed, 2016-03-02, 16:23

Re: Offis dcmtk-3.6.1_20160216: Memory Leaks

#3 Post by fgigante »

I don't know how the enable the output filename and the code memory leak line.

Can you reproduce the memory leak by yourself by means of the details of my first post?

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: Offis dcmtk-3.6.1_20160216: Memory Leaks

#4 Post by J. Riesmeier »

There was also an unanswered question from our email communication:
Do you also observe such memory leaks when using any other DCMTK tool, e.g.
when calling dcmdump from a thread? I'm asking because it could be a general
problem, e.g. with the global data dictionary or the logger class.

ionut.vaida
Posts: 24
Joined: Fri, 2016-12-02, 09:51

Re: Offis dcmtk-3.6.1_20160216: Memory Leaks

#5 Post by ionut.vaida »

Hello,
I just move my project from dcmtk 3.6.0 to 3.6.2, and visual leak detector detects memory leaks.
Tool say that is a problem in ofstrinc.cc file in this method:

OFString::reserve (size_t res_arg)
{
if (res_arg == OFString_npos) {
res_arg = 0; /* let at least space for eos get reserved */
}
res_arg++; /* add space for eos */
if (this->theCapacity < res_arg) {
char* newstr = new char[res_arg];
if (newstr) {
size_t usedSpace = 0;
this->theCapacity = res_arg - 1; /* not the eos */
if (this->size() > 0) {
const size_t len = size();
// copyMem() because theCString could have null bytes
OFBitmanipTemplate<char>::copyMem(this->theCString, newstr, len);
usedSpace = len;
}
OFBitmanipTemplate<char>::zeroMem(newstr + usedSpace, res_arg - usedSpace);
char* oldstr = this->theCString;
this->theCString = newstr;
delete[] oldstr;
} else {
OFSTRING_MEMORYALLOCERROR(newstr);
}
}
}

Leaks is detected at "newstr". I think that pointer newstr need to be deleted .

Thank you

Jan Schlamelcher
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 318
Joined: Mon, 2014-03-03, 09:51
Location: Oldenburg, Germany

Re: Offis dcmtk-3.6.1_20160216: Memory Leaks

#6 Post by Jan Schlamelcher »

This looks like a false positive of the leak detector on the first glance, since newstr is assigned to one of the member variables some lines below and should therefore be cleaned up in the destructor as intended

Code: Select all

this->theCString = newstr;
Perhaps the destructor of your OFString object isn't called since it is the end of the program execution anyway (some compilers optimize this and simply don't delete memory just befor exiting the program since the operating system will cleanup afterwards anyway).

ionut.vaida
Posts: 24
Joined: Fri, 2016-12-02, 09:51

Re: Offis dcmtk-3.6.1_20160216: Memory Leaks

#7 Post by ionut.vaida »

Yes you are right but this memory leaks appears when i use dcmtk logger in multithread app.
Same code with dcmtk 3.6.0 do not have leaks. i think i do something wrong.

DCMNET_INFO("Sending N-ACTION Request"); - this is one line where i got leak

Is some define that i need to declare for using logger in multithreading app?

This is output of VLD:

Call Stack (TID 1556):
ntdll.dll!RtlAllocateHeap()
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\afxmem.cpp (336): DicomViewer.exe!operator new[]() + 0x9 bytes
d:\_work\_library\dcmtk 3.6.2 vs2017\dcmtk-3.6.2\ofstd\libsrc\ofstring.cc (403): DicomViewer.exe!OFString::reserve() + 0x9 bytes
d:\_work\_library\dcmtk 3.6.2 vs2017\dcmtk-3.6.2\ofstd\libsrc\ofstring.cc (223): DicomViewer.exe!OFString::assign()
d:\_work\_library\dcmtk 3.6.2 vs2017\dcmtk-3.6.2\ofstd\libsrc\ofstring.cc (239): DicomViewer.exe!OFString::assign()
d:\_work\_library\dcmtk 3.6.2 vs2017\dcmtk-3.6.2\ofstd\libsrc\ofstring.cc (130): DicomViewer.exe!OFString::operator=()
d:\_work\_library\dcmtk 3.6.2 vs2017\dcmtk-3.6.2\oflog\libsrc\logevent.cc (160): DicomViewer.exe!dcmtk::log4cplus::spi::InternalLoggingEvent::setLoggingEvent()
d:\_work\_library\dcmtk 3.6.2 vs2017\dcmtk-3.6.2\oflog\libsrc\logmacro.cc (85): DicomViewer.exe!dcmtk::log4cplus::detail::macro_forced_log()
d:\_work\dicom viewer 2d_2017\dcmtk viewer\dcmscuex.cpp (449): DicomViewer.exe!DcmSCUEx::closeAssociation() + 0xEC bytes
d:\_work\dicom viewer 2d_2017\dcmtk viewer\waitdlg.cpp (7479): DicomViewer.exe!CWaitDlg::DcmCheckUpdate() + 0x1D bytes
d:\_work\dicom viewer 2d_2017\dcmtk viewer\waitdlg.cpp (6281): DicomViewer.exe!CWaitDlg::CheckUpdateThread() + 0xC bytes
KERNEL32.DLL!BaseThreadInitThunk() + 0x24 bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x137 bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x107 bytes
Data:
64 63 6D 74 6B 2E 64 63 6D 6E 65 74 00 dcmtk.dc mnet....


Visual Leak Detector detected 23 memory leaks (2888 bytes).
Largest number used: 1168526 bytes.
Total allocations: 8227086 bytes.
Visual Leak Detector is now exiting.
The program '[16204] DicomViewer.exe' has exited with code 0 (0x0).

Post Reply

Who is online

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