[apologies if this is a duplicate, my original submission seems to have
gone missing]
Hi All,
I've encountered what appears to be a memory leak when DOMParser::parse()
is invoked under some circumstances. This occurs when linking against a
static version of Xerces-C 1.4 built using Borland C/C++ 5.5.1 (SP2) +
STLPort. Experimentation has shown that each call to parse() leaks 128KB of
memory -- quite a lot, especially considering our application needs to
invoke parse() thousands of times per second. The smallest program which
demonstrates the problem for us is:
#include <iostream>
#include <util/PlatformUtils.hpp>
#include <parsers/DOMParser.hpp>
int main(int argc, char *argv[])
{
if(argv[1])
{
XMLPlatformUtils::Initialize();
DOMParser *parser = new DOMParser;
parser->setValidationScheme(DOMParser::Val_Never);
try
{
parser->parse(argv[1]);
}
catch(...)
{
std::cerr << "Warning: XML errors encountered."
<< std::endl;
}
delete parser;
XMLPlatformUtils::Terminate();
}
else
std::cout << "No filename given." << std::endl;
return 0;
}
The leak is observed with the following input:
<?xml version="1.0"?>
<!DOCTYPE group SYSTEM "project-team.dtd">
<group name="department">
<team name="project">
<person name="A" leader="true"/>
<person name="B"/>
<person name="C"/>
<person name="D"/>
</team>
</group>
and the referred DTD being:
<!-- DTD for our sample xml stuff -->
<!ELEMENT group (team*) >
<!ATTLIST group name CDATA #REQUIRED >
<!ELEMENT team (person*) >
<!ATTLIST team name CDATA #REQUIRED >
<!ELEMENT person EMPTY >
<!ATTLIST person name CDATA #REQUIRED >
<!ATTLIST person leader CDATA "false" >
However, if we remove the <!DOCTYPE> line, then no memory leak is observed
with:
<?xml version="1.0"?>
<group name="department">
<team name="project">
<person name="A" leader="true"/>
<person name="B"/>
<person name="C"/>
<person name="D"/>
</team>
</group>
According to a memory-leak detection tool (memproof), the leaked resources
are:
338 Virtual
Memory $02210000 4096 VirtualAlloc(02210000,4096,4096,4)
$0005C566 C:\EI\leaky.exe
$0005D0F3 C:\EI\leaky.exe
$0005CF13 C:\EI\leaky.exe
$0005C674 C:\EI\leaky.exe
$0005BF85 C:\EI\leaky.exe
$000149D4 createReader in ReaderMgr.cpp (445) C:\EI\leaky.exe
$0001F00A @XMLScanner@scanReset in XMLScanner2.cpp (784) C:\EI\leaky.exe
$0001949D scanDocument in XMLScanner.cpp (274) C:\EI\leaky.exe
$000193C8 scanDocument in XMLScanner.cpp (240) C:\EI\leaky.exe
$00019437 scanDocument in XMLScanner.cpp (249) C:\EI\leaky.exe
$00022BE5 parse in DOMParser.cpp (294) C:\EI\leaky.exe
$0000024B main in leaky.cc (14) C:\EI\leaky.exe
$00064E69 C:\EI\leaky.exe
339 Virtual
Memory $02211000 4096 VirtualAlloc(02211000,4096,4096,4)
[same call-stack]
340 Virtual
Memory $02212000 4096 VirtualAlloc(02212000,4096,4096,4)
[same call-stack]
341 Virtual
Memory $02213000 4096 VirtualAlloc(02213000,4096,4096,4)
[same call-stack]
342 Virtual
Memory $02214000 4096 VirtualAlloc(02214000,4096,4096,4)
[same call-stack]
343 Virtual
Memory $02215000 4096 VirtualAlloc(02215000,4096,4096,4)
[same call-stack]
344 Virtual
Memory $02216000 4096 VirtualAlloc(02216000,4096,4096,4)
[same call-stack]
345 Virtual
Memory $02217000 4096 VirtualAlloc(02217000,4096,4096,4)
[same call-stack]
346 Virtual
Memory $02218000 4096 VirtualAlloc(02218000,4096,4096,4)
[same call-stack]
347 Virtual
Memory $02219000 4096 VirtualAlloc(02219000,4096,4096,4)
[same call-stack]
348 Virtual
Memory $0221A000 4096 VirtualAlloc(0221A000,4096,4096,4)
[same call-stack]
349 Virtual
Memory $0221B000 4096 VirtualAlloc(0221B000,4096,4096,4)
[same call-stack]
350 Virtual
Memory $0221C000 4096 VirtualAlloc(0221C000,4096,4096,4)
[same call-stack]
351 Virtual
Memory $0221D000 4096 VirtualAlloc(0221D000,4096,4096,4)
[same call-stack]
352 Virtual
Memory $0221E000 4096 VirtualAlloc(0221E000,4096,4096,4)
[same call-stack]
353 Virtual
Memory $0221F000 4096 VirtualAlloc(0221F000,4096,4096,4)
[same call-stack]
354 Virtual
Memory $02220000 4096 VirtualAlloc(02220000,4096,4096,4)
[same call-stack]
355 Virtual
Memory $02221000 4096 VirtualAlloc(02221000,4096,4096,4)
[same call-stack]
356 Virtual
Memory $02222000 4096 VirtualAlloc(02222000,4096,4096,4)
[same call-stack]
357 Virtual
Memory $02223000 4096 VirtualAlloc(02223000,4096,4096,4)
[same call-stack]
358 Virtual
Memory $02224000 4096 VirtualAlloc(02224000,4096,4096,4)
[same call-stack]
359 Virtual
Memory $02225000 4096 VirtualAlloc(02225000,4096,4096,4)
[same call-stack]
360 Virtual
Memory $02226000 4096 VirtualAlloc(02226000,4096,4096,4)
[same call-stack]
361 Virtual
Memory $02227000 4096 VirtualAlloc(02227000,4096,4096,4)
[same call-stack]
362 Virtual
Memory $02228000 4096 VirtualAlloc(02228000,4096,4096,4)
[same call-stack]
363 Virtual
Memory $02229000 4096 VirtualAlloc(02229000,4096,4096,4)
[same call-stack]
364 Virtual
Memory $0222A000 4096 VirtualAlloc(0222A000,4096,4096,4)
[same call-stack]
365 Virtual
Memory $0222B000 4096 VirtualAlloc(0222B000,4096,4096,4)
[same call-stack]
366 Virtual
Memory $0222C000 4096 VirtualAlloc(0222C000,4096,4096,4)
[same call-stack]
367 Virtual
Memory $0222D000 4096 VirtualAlloc(0222D000,4096,4096,4)
[same call-stack]
368 Virtual
Memory $0222E000 4096 VirtualAlloc(0222E000,4096,4096,4)
[same call-stack]
369 Virtual
Memory $0222F000 4096 VirtualAlloc(0222F000,4096,4096,4)
The call-stack given corresponds to a new XMLReader instance being
allocated on the heap. It would appear, from debugging statements I
inserted into the library, that every constructor call is matched by a
destructor call and all dynamically allocated data members of this class
appear to be cleaned-up correctly by the destructor.
I haven't been able to confirm if the same problem exists under Xerces-C
1.5 due to the lengthy process involved in compiling Xerces-C under Borland
C/C++ 5.5.1. However at this point I'm pretty-much stuck and would
appreciate any comments people might have on where the problem might be and
how to proceed from here.
Thanks in advance,
- Andrew
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]