You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@xerces.apache.org by Sajit Zachariah <sa...@yahoo.com> on 2007/09/06 13:58:47 UTC

Crash on DOMNode release

Hi,

I am using XercesC 2.8.0. 

I parse an XML string using the following method

DOMNode* ClXMLDOMParser::loadString(char* _xmlString)
{
  
   XercesDOMParser* ao_Parser = new XercesDOMParser();
  
ao_Parser->setValidationScheme(XercesDOMParser::Val_Auto);
//optional.
   ao_Parser->setDoNamespaces(true); // optional

   ao_Parser->setErrorHandler(domHandler);

   // START OF PARSING
   bool errorsOccured = false;
   try
   {
      XMLTransService* pTransService =
XMLPlatformUtils::fgTransService;
   	XMLLCPTranscoder* pLCPTranscoder =
pTransService->makeNewLCPTranscoder();
      XMLCh* xmlString =
XMLString::transcode(_xmlString);
		XMLByte* strByte =
(XMLByte*)pLCPTranscoder->transcode(xmlString);

	  	MemBufInputSource xmlBuffer (strByte
,strlen(_xmlString)
                     ,XMLString::transcode("strXML")
,false);

		ao_Parser->parse( xmlBuffer );
      DOMNode* domNode =   ao_Parser->adoptDocument();
      // MEM_LEAK_CHECK - Delete added, Release memory
      XMLString::release(&xmlString);
      XMLString::release(&strByte);
      if(ao_Parser)
         delete ao_Parser;

      return domNode;
   }
   catch (const OutOfMemoryException& oe)
   {
      // MEM_LEAK_CHECK - Delete added
      if(ao_Parser)
         delete ao_Parser;
       XERCES_STD_QUALIFIER cerr <<
"OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
       errorsOccured = true;
   }
   catch (const XMLException& e)
   {
      // MEM_LEAK_CHECK - Delete added
      if(ao_Parser)
         delete ao_Parser;
      XERCES_STD_QUALIFIER cerr << "An error occurred
during parsing "
               << XERCES_STD_QUALIFIER endl ;

      errorsOccured = true;
   }
   catch (const DOMException& e)
   {
      // MEM_LEAK_CHECK - Delete added
      if(ao_Parser)
         delete ao_Parser;
      XERCES_STD_QUALIFIER cerr << "DOMException code
is:  " << e.code << XERCES_STD_QUALIFIER endl;
   }

   catch (...)
   {
      // MEM_LEAK_CHECK - Delete added
      if(ao_Parser)
         delete ao_Parser;
      XERCES_STD_QUALIFIER cerr << "An error occurred
during parsing\n " << XERCES_STD_QUALIFIER endl;
       errorsOccured = true;
   }
    // END OF PARSING
}

returned node is again iterated and I create a
composite of the domnode for the use. And finally when
I try to delete the node a access violation exception
is thrown. Please note that I am using Borland C++
Builder
Please see the code that calls the above method

void ClXMLBase::loadXmlString(char* _cn_xmlString)
{

   int i_StringLen = strlen(_cn_xmlString);

   if(i_StringLen!=0)
   {      
      ClXMLDOMParser o_DOMParser;
      m_RootNode =
o_DOMParser.loadString(_cn_xmlString);//call to load
string
      DOMNodeList* ao_Node_List =
m_RootNode->getChildNodes();

      for(int i=0; i < (int)ao_Node_List->getLength();
i++)
      {
         DOMNode* ao_ParentNode =
ao_Node_List->item(i);

         if(ao_ParentNode == NULL ||
ao_ParentNode->getNodeType() != DOMNode::ELEMENT_NODE)
            continue;

         this->parse(ao_ParentNode);
      }

   }
   // m_RootNode->release(); //This works ut if I call
releaseNode() just after this loadXmlstring with the
object it crashes

}


Your help on this is greately appreciated.

Regards
-Sajit


       
____________________________________________________________________________________
Need a vacation? Get great deals
to amazing places on Yahoo! Travel.
http://travel.yahoo.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: c-dev-help@xerces.apache.org


Re: Crash on DOMNode release

Posted by Boris Kolpackov <bo...@codesynthesis.com>.
Hi Sajit,

Sajit Zachariah <sa...@yahoo.com> writes:

> Thanks David for the inputs regarding memory leak. It
> has helped but still I see a major leak when I run
> this parsing multiple times.

Why don't you run your program under a memory checker like
valgrind (Linux/UNIX) or equivalent? It will allow you to
pin-point the location where leaked memory is allocated.

If you still believe this memory leak is a bug in Xerces-C++
then we will need a small, compilable test case (including XML
file) that reproduces this problem. You can create a bug report
for this problem and attach the files to it:


http://issues.apache.org/jira/browse/XERCESC


Boris

-- 
Boris Kolpackov
Code Synthesis Tools CC
http://www.codesynthesis.com
Open-Source, Cross-Platform C++ XML Data Binding

---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: c-dev-help@xerces.apache.org


Re: Crash on DOMNode release

Posted by Sajit Zachariah <sa...@yahoo.com>.
Thanks David for the inputs regarding memory leak. It
has helped but still I see a major leak when I run
this parsing multiple times. 

Thanks for the extra inputs (code review comments)
that you gave also.


--- David Bertoni <db...@apache.org> wrote:

> Sajit Zachariah wrote:
> > Hi,
> > 
> > I am using XercesC 2.8.0. 
> > 
> > I parse an XML string using the following method
> ...
> >       XMLCh* xmlString =
> > XMLString::transcode(_xmlString);
> > 		XMLByte* strByte =
> > (XMLByte*)pLCPTranscoder->transcode(xmlString);
> > 
> > 	  	MemBufInputSource xmlBuffer (strByte
> > ,strlen(_xmlString)
> >                     
> ,XMLString::transcode("strXML")
> > ,false);
> Some comments unrelated to your crash:
> 
> 1. Don't you think it's a bit confusing to have a
> variable xmlString that 
> shadows the formal parameter xmlString?
> 
> 2. There is no difference between using
> XMLString::transcode() and using a 
> local code page transcoder, so you don't need to mix
> the two.
> 
> 3. Please make sure the string you pass in is
> encoded in the local code 
> page.  Otherwise, you are asking for trouble.  It
> would be far better, 
> easier, and safer to pass the char* into the
> MemBufInputSource instance, 
> and let the parser figure out the document's
> encoding.
> 
> 4. The call to XMLString::transcode("strXML") is a
> memory leak.  If you 
> really are going to use an invariant string for the
> system ID, it would be 
> better to create a wide character string using the
> static constants in 
> xercesc/util/XMLUniDefs.hpp:
> 
> const XMLCh  systemID[] =
> {
>      chLatin_s,
>      chLatin_t,
>      chLatin_r,
>      chLatin_X,
>      chLatin_M,
>      chLatin_L,
>      chNull
> };
> 
> > 
> > 		ao_Parser->parse( xmlBuffer );
> >       DOMNode* domNode =  
> ao_Parser->adoptDocument();
> >       // MEM_LEAK_CHECK - Delete added, Release
> memory
> >       XMLString::release(&xmlString);
> >       XMLString::release(&strByte);
> >       if(ao_Parser)
> >          delete ao_Parser;
> There is no way ao_Parser can ever be a null pointer
> in your code.  And 
> even if it is, you never have to check before
> deleting a null pointer.
> 
> > 
> >       return domNode;
> >    }
> >    catch (const OutOfMemoryException& oe)
> >    {
> >       // MEM_LEAK_CHECK - Delete added
> >       if(ao_Parser)
> >          delete ao_Parser;
> ditto...
> >        XERCES_STD_QUALIFIER cerr <<
> > "OutOfMemoryException" << XERCES_STD_QUALIFIER
> endl;
> >        errorsOccured = true;
> >    }
> >    catch (const XMLException& e)
> >    {
> >       // MEM_LEAK_CHECK - Delete added
> >       if(ao_Parser)
> >          delete ao_Parser;
> ditto...
> >       XERCES_STD_QUALIFIER cerr << "An error
> occurred
> > during parsing "
> >                << XERCES_STD_QUALIFIER endl ;
> > 
> >       errorsOccured = true;
> >    }
> >    catch (const DOMException& e)
> >    {
> >       // MEM_LEAK_CHECK - Delete added
> >       if(ao_Parser)
> >          delete ao_Parser;
> ditto...
> >       XERCES_STD_QUALIFIER cerr << "DOMException
> code
> > is:  " << e.code << XERCES_STD_QUALIFIER endl;
> >    }
> > 
> >    catch (...)
> >    {
> >       // MEM_LEAK_CHECK - Delete added
> >       if(ao_Parser)
> >          delete ao_Parser;
> ditto...
> >       XERCES_STD_QUALIFIER cerr << "An error
> occurred
> > during parsing\n " << XERCES_STD_QUALIFIER endl;
> >        errorsOccured = true;
> >    }
> >     // END OF PARSING
> > }
> There is a very nice class in Xerces-C called
> Janitor 
> (xercesc/util/Janitor.hpp that implements an
> auto_ptr-like class that can 
> clean up the parser instance for you, instead of
> worrying about deleting 
> it.  You can grep the code for "Janitor" to see how
> it's used.
> 
> > 
> > returned node is again iterated and I create a
> > composite of the domnode for the use. And finally
> when
> > I try to delete the node a access violation
> exception
> > is thrown. Please note that I am using Borland C++
> > Builder
> > Please see the code that calls the above method
> > 
> > void ClXMLBase::loadXmlString(char* _cn_xmlString)
> > {
> > 
> >    int i_StringLen = strlen(_cn_xmlString);
> > 
> >    if(i_StringLen!=0)
> >    {      
> >       ClXMLDOMParser o_DOMParser;
> >       m_RootNode =
> > o_DOMParser.loadString(_cn_xmlString);//call to
> load
> > string
> >       DOMNodeList* ao_Node_List =
> > m_RootNode->getChildNodes();
> > 
> >       for(int i=0; i <
> (int)ao_Node_List->getLength();
> > i++)
> >       {
> >          DOMNode* ao_ParentNode =
> > ao_Node_List->item(i);
> > 
> >          if(ao_ParentNode == NULL ||
> > ao_ParentNode->getNodeType() !=
> DOMNode::ELEMENT_NODE)
> >             continue;
> > 
> >          this->parse(ao_ParentNode);
> >       }
> > 
> >    }
> >    // m_RootNode->release(); //This works ut if I
> call
> > releaseNode() just after this loadXmlstring with
> the
> > object it crashes
> This could be caused my many things.  Perhaps your
> previous code has an 
> error and the heap is corrupted.  Perhaps some other
> code has already 
> released the DOMDocument instance.  I would suggest
> some debugging with a 
> good debugger and heap-checking library.  I'm not
> sure what your "parse" 
> member function does, but if you comment that call
> out, and you don't 
> experience a crash, then I'd say that's the culprit.
> 
> Dave
> 
>
---------------------------------------------------------------------
> To unsubscribe, e-mail:
> c-dev-unsubscribe@xerces.apache.org
> For additional commands, e-mail:
> c-dev-help@xerces.apache.org
> 
> 



      ____________________________________________________________________________________
Check out the hottest 2008 models today at Yahoo! Autos.
http://autos.yahoo.com/new_cars.html

---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: c-dev-help@xerces.apache.org


Re: Crash on DOMNode release

Posted by David Bertoni <db...@apache.org>.
Sajit Zachariah wrote:
> Hi,
> 
> I am using XercesC 2.8.0. 
> 
> I parse an XML string using the following method
...
>       XMLCh* xmlString =
> XMLString::transcode(_xmlString);
> 		XMLByte* strByte =
> (XMLByte*)pLCPTranscoder->transcode(xmlString);
> 
> 	  	MemBufInputSource xmlBuffer (strByte
> ,strlen(_xmlString)
>                      ,XMLString::transcode("strXML")
> ,false);
Some comments unrelated to your crash:

1. Don't you think it's a bit confusing to have a variable xmlString that 
shadows the formal parameter xmlString?

2. There is no difference between using XMLString::transcode() and using a 
local code page transcoder, so you don't need to mix the two.

3. Please make sure the string you pass in is encoded in the local code 
page.  Otherwise, you are asking for trouble.  It would be far better, 
easier, and safer to pass the char* into the MemBufInputSource instance, 
and let the parser figure out the document's encoding.

4. The call to XMLString::transcode("strXML") is a memory leak.  If you 
really are going to use an invariant string for the system ID, it would be 
better to create a wide character string using the static constants in 
xercesc/util/XMLUniDefs.hpp:

const XMLCh  systemID[] =
{
     chLatin_s,
     chLatin_t,
     chLatin_r,
     chLatin_X,
     chLatin_M,
     chLatin_L,
     chNull
};

> 
> 		ao_Parser->parse( xmlBuffer );
>       DOMNode* domNode =   ao_Parser->adoptDocument();
>       // MEM_LEAK_CHECK - Delete added, Release memory
>       XMLString::release(&xmlString);
>       XMLString::release(&strByte);
>       if(ao_Parser)
>          delete ao_Parser;
There is no way ao_Parser can ever be a null pointer in your code.  And 
even if it is, you never have to check before deleting a null pointer.

> 
>       return domNode;
>    }
>    catch (const OutOfMemoryException& oe)
>    {
>       // MEM_LEAK_CHECK - Delete added
>       if(ao_Parser)
>          delete ao_Parser;
ditto...
>        XERCES_STD_QUALIFIER cerr <<
> "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
>        errorsOccured = true;
>    }
>    catch (const XMLException& e)
>    {
>       // MEM_LEAK_CHECK - Delete added
>       if(ao_Parser)
>          delete ao_Parser;
ditto...
>       XERCES_STD_QUALIFIER cerr << "An error occurred
> during parsing "
>                << XERCES_STD_QUALIFIER endl ;
> 
>       errorsOccured = true;
>    }
>    catch (const DOMException& e)
>    {
>       // MEM_LEAK_CHECK - Delete added
>       if(ao_Parser)
>          delete ao_Parser;
ditto...
>       XERCES_STD_QUALIFIER cerr << "DOMException code
> is:  " << e.code << XERCES_STD_QUALIFIER endl;
>    }
> 
>    catch (...)
>    {
>       // MEM_LEAK_CHECK - Delete added
>       if(ao_Parser)
>          delete ao_Parser;
ditto...
>       XERCES_STD_QUALIFIER cerr << "An error occurred
> during parsing\n " << XERCES_STD_QUALIFIER endl;
>        errorsOccured = true;
>    }
>     // END OF PARSING
> }
There is a very nice class in Xerces-C called Janitor 
(xercesc/util/Janitor.hpp that implements an auto_ptr-like class that can 
clean up the parser instance for you, instead of worrying about deleting 
it.  You can grep the code for "Janitor" to see how it's used.

> 
> returned node is again iterated and I create a
> composite of the domnode for the use. And finally when
> I try to delete the node a access violation exception
> is thrown. Please note that I am using Borland C++
> Builder
> Please see the code that calls the above method
> 
> void ClXMLBase::loadXmlString(char* _cn_xmlString)
> {
> 
>    int i_StringLen = strlen(_cn_xmlString);
> 
>    if(i_StringLen!=0)
>    {      
>       ClXMLDOMParser o_DOMParser;
>       m_RootNode =
> o_DOMParser.loadString(_cn_xmlString);//call to load
> string
>       DOMNodeList* ao_Node_List =
> m_RootNode->getChildNodes();
> 
>       for(int i=0; i < (int)ao_Node_List->getLength();
> i++)
>       {
>          DOMNode* ao_ParentNode =
> ao_Node_List->item(i);
> 
>          if(ao_ParentNode == NULL ||
> ao_ParentNode->getNodeType() != DOMNode::ELEMENT_NODE)
>             continue;
> 
>          this->parse(ao_ParentNode);
>       }
> 
>    }
>    // m_RootNode->release(); //This works ut if I call
> releaseNode() just after this loadXmlstring with the
> object it crashes
This could be caused my many things.  Perhaps your previous code has an 
error and the heap is corrupted.  Perhaps some other code has already 
released the DOMDocument instance.  I would suggest some debugging with a 
good debugger and heap-checking library.  I'm not sure what your "parse" 
member function does, but if you comment that call out, and you don't 
experience a crash, then I'd say that's the culprit.

Dave

---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: c-dev-help@xerces.apache.org