xerces-c-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alberto Massari <amass...@datadirect.com>
Subject Re: Core Dump while releasing Parser ressources...
Date Mon, 18 May 2009 08:34:31 GMT
In order to release the DOM trees owned by the parser, you either delete 
the parser or call resetDocumentPool(). The reset() method is simply 
initializing the internal variables before a parsing operation starts.

    /** Reset the parser
      *
      * This method resets the state of the DOM driver and makes
      * it ready for a fresh parse run.
      */
    void reset();


    /** Reset the documents vector pool and release all the associated 
memory
      * back to the system.
      *
      * When parsing a document using a DOM parser, all memory allocated
      * for a DOM tree is associated to the DOM document.
      *
      * If you do multiple parse using the same DOM parser instance, then
      * multiple DOM documents will be generated and saved in a vector pool.
      * All these documents (and thus all the allocated memory)
      * won't be deleted until the parser instance is destroyed.
      *
      * If you don't need these DOM documents anymore and don't want to
      * destroy the DOM parser instance at this moment, then you can 
call this method
      * to reset the document vector pool and release all the allocated 
memory
      * back to the system.
      *
      * It is an error to call this method if you are in the middle of a
      * parse (e.g. in the mid of a progressive parse).
      *
      * @exception IOException An exception from the parser if this function
      *            is called when a parse is in progress.
      *
      */
    void resetDocumentPool();

Alberto

radada ha scritto:
> God this library is hard to use : (
> So : the core dump is gone, thanks : ) (I removed the call to release and
> the deletion of the DOMDocument)
> But (there's always a but...), I get a memory leak now. This is why is used
> the reset() method on the parser at first I think.
> The only way to release a parser and its associated objects is to delete it
> or is there another method to call?
> Thanks, again : /
>
>
> Alberto Massari wrote:
>   
>> If you use XercesDOMParser::getDocument to retrieve the parsed 
>> DOMDocument, you should NOT call either DOMDocument::release or delete 
>> the object, as the DOM tree is owned by the parsed and will be deleted 
>> by him when you release it.
>> If you are going to keep the parser for a long time, you may want to 
>> handle the lifetime of the DOM tree yourself; but in that case you 
>> should retrieve it from the parser by using 
>> XercesDOMParser::adoptDocument, and you will have to use 
>> DOMDocument::release to free it (don't use "delete" as it will not 
>> perform all the cleanup, and in any case you are not assured it has been 
>> created by the same "new" operator matching your "delete" operator).
>>
>> Alberto
>>
>> P.S. it is written in the documentation as well:
>>
>>     /** Get the DOM document
>>       *
>>       * This method returns the DOMDocument object representing the
>>       * root of the document tree. This object provides the primary
>>       * access to the document's data.
>>       *
>>       * The returned DOMDocument object is owned by the parser.
>>       *
>>       * @return The DOMDocument object which represents the entire
>>       *         XML document.
>>       */
>>     DOMDocument* getDocument();
>>
>>     /** Adopt the DOM document
>>       *
>>       * This method returns the DOMDocument object representing the
>>       * root of the document tree.
>>       *
>>       * The caller will adopt the DOMDocument and thus is responsible to
>>       * call DOMDocument::release() to release the associated memory.
>>       * The parser will not delete it.   The ownership is transferred
>>       * from the parser to the caller.
>>       *
>>       * @return The adopted DOMDocument object which represents the entire
>>       *         XML document.
>>       */
>>     DOMDocument* adoptDocument();
>>
>>
>>
>> radada ha scritto:
>>     
>>> Thanks Alberto, but I'm perplex now : should I call the release method on
>>> the
>>> DOMDocument ou should I just delete it w/o calling release?
>>> Thx man : )
>>>
>>>
>>> Alberto Massari wrote:
>>>   
>>>       
>>>> You shouldn't explicitly release a DOMDocument unless you adopted it 
>>>> from the DOMParser, or it will try to release it after it has already 
>>>> been deleted.
>>>> You shouldn't also attempt to delete an object that you already
>>>> released.
>>>>
>>>> Alberto
>>>>
>>>> radada ha scritto:
>>>>     
>>>>         
>>>>> Hi there : )
>>>>>
>>>>> I think I'm going nuts : (
>>>>> Thanks to Alberto, I've got a code which is approximatively good. As
>>>>> told
>>>>> in
>>>>> a previous post, I implemented a functional layer over the xerces
>>>>> library
>>>>> so
>>>>> that we can use it in our software at work.
>>>>> In order to control as much as possible the memory leaks, I created a
>>>>> singleton which can (and only it can) create DOMDocument and
>>>>> XercesDOMParser. It is reponsible too for the releasing of the objets.
>>>>>
>>>>> So for the parser, I've got a release method : 
>>>>>
>>>>> void XMLFactory::releaseParser(ParserXML* p_poParser)
>>>>> {  
>>>>>    #ifdef AFF
>>>>>       cout << "XMLFactory::releaseParser()" << endl;
>>>>>    #endif
>>>>>
>>>>>
>>>>>    // suppression en se basant sur les adresses des objets
>>>>>    for (int i=0; i<m_oListeParserXML.entries(); i++)
>>>>>    {
>>>>>       ParserXML* ptr = NULL;
>>>>>       ptr = m_oListeParserXML.at(i);
>>>>>       if (ptr == p_poParser)
>>>>>          m_oListeParserXML.removeAt(i);
>>>>>    }
>>>>>       
>>>>>    // on delete l'objet (on test avant s'il n'est pas NULL avec le
>>>>> ThrowIfNullWithMsg)
>>>>>    DeleteIfObject(p_poParser);
>>>>> }
>>>>>
>>>>> In the destructor of the Parser, I've got this : 
>>>>>
>>>>> ParserXML::~ParserXML()
>>>>> {   
>>>>>    #ifdef AFF
>>>>>       cout << "Destructeur de ParserXML" << endl;
>>>>>    #endif
>>>>>    
>>>>>    if (m_poDocument != NULL)
>>>>>    {
>>>>>       m_poDocument->release();
>>>>>    }
>>>>>    m_poDOMParser->reset();
>>>>>
>>>>>    DeleteIfObject(m_poDOMParser);
>>>>>    DeleteIfObject(m_poErrorHandler);
>>>>>    DeleteIfObject(m_poDOMDocument);
>>>>>    DeleteIfObject(m_poElementXML);
>>>>> }
>>>>>
>>>>> Some strange things happen, especially when I compare my code to the
>>>>> DOM
>>>>> Programming Guide Chapter "Constructing a XercesDOMParser"
>>>>> (http://xerces.apache.org/xerces-c/program-dom-3.html). It seems that,
>>>>> to
>>>>> delete a parser and its ressources, one only have to delete the parser.
>>>>> If I do that, I get a core Dump while deleting the DOMDocument.
>>>>> So I added a m_poDOMParser->resetDocumentPool(), but it had the same
>>>>> effect.
>>>>> Then I tried with m_poDOMParser->reset() and it did work! Well, not
>>>>> that
>>>>> much. Sometimes it does, sometimes it doesn't. I still get a core Dump
>>>>> sometimes, always when deleting the parser...
>>>>>
>>>>> Just for the record, here is the parsing method : 
>>>>>
>>>>>  ElementXML* ParserXML::parse(const char* p_pcBuffer)
>>>>> {
>>>>>    #ifdef AFF
>>>>>       cout << "ParserXML::parse()" << endl;
>>>>>    #endif
>>>>>       
>>>>>    // Si aucun buffer n'est passé, on renvoie NULL
>>>>>    if (p_pcBuffer == NULL)
>>>>>    {
>>>>>       return NULL;
>>>>>    }
>>>>>    
>>>>>    // si le parser n'a pas libéré les ressources du précédent parse
  
>>>>>    if (m_bDocumentParsed)
>>>>>    {
>>>>>       if (m_poDocument != NULL)
>>>>>       {
>>>>>          m_poDocument->release();
>>>>>       }
>>>>>       m_poDOMParser->reset();
>>>>>       m_bDocumentParsed = false;
>>>>>    }
>>>>>    
>>>>>    char* l_pcMessage;
>>>>>    // on crée un objet pour le parsing
>>>>>    MemBufInputSource l_oInputSource((const XMLByte*)p_pcBuffer,
>>>>>                                     strlen(p_pcBuffer),
>>>>>                                     (const XMLCh*)  "ParserXML");
>>>>>    try
>>>>>    {
>>>>>       // on parse
>>>>>       m_poDOMParser->parse(l_oInputSource);
>>>>>       
>>>>>       // on récupère le DOMDocument parsé
>>>>>       m_poDocument = m_poDOMParser->getDocument();
>>>>>       
>>>>>       // on libère la mémoire si besoin
>>>>>       DeleteIfObject(m_poElementXML);
>>>>>       //on crée un nouveau ElementXML avec les données du DOMDocument
>>>>>       m_poElementXML = new
>>>>> ElementXML(m_poDocument->getDocumentElement());
>>>>>       // on indique que le Document a été correctement parsé
>>>>>       m_bDocumentParsed = true;
>>>>>       // on retourne l'ElementXML ainsi créé
>>>>>       return m_poElementXML;
>>>>>    }
>>>>>    catch(XMLException& XMLEx)
>>>>>    {
>>>>>       l_pcMessage = XMLString::transcode(XMLEx.getMessage());
>>>>>       ExceptMessage ex("T00500", "XML Exception", l_pcMessage);
>>>>>       XMLString::release(&l_pcMessage);
>>>>>       ex.doThrow();
>>>>>    }
>>>>>    catch(DOMException& DOMEx)
>>>>>    {
>>>>>       l_pcMessage = XMLString::transcode(DOMEx.msg);
>>>>>       ExceptMessage ex("T00501", "XML Exception", l_pcMessage);
>>>>>       XMLString::release(&l_pcMessage);
>>>>>       ex.doThrow();
>>>>>    }
>>>>>    catch(SAXParseException& SaxParseEx)
>>>>>    {
>>>>>       l_pcMessage = XMLString::transcode(SaxParseEx.getMessage());
>>>>>       ExceptMessage ex("T00502", "SAXParse Exception", l_pcMessage);
>>>>>       XMLString::release(&l_pcMessage);
>>>>>       ex.doThrow();
>>>>>    }
>>>>>    catch(SAXException& SaxEx)
>>>>>    {
>>>>>       l_pcMessage = XMLString::transcode(SaxEx.getMessage());
>>>>>       ExceptMessage ex("T00502", "SAX Exception", l_pcMessage);
>>>>>       XMLString::release(&l_pcMessage);
>>>>>       ex.doThrow();
>>>>>    }
>>>>>    catch(...)
>>>>>    {
>>>>>       ExceptMessage ex("T00450", " ", "Erreur inconnue");
>>>>>       ex.doThrow();
>>>>>    }
>>>>> }
>>>>>
>>>>> You just can't imagine how happy will I be when I won't have to code
>>>>> into
>>>>> this libraby :D
>>>>> Anyway, as always, if you find something weird, or even the tinniest
>>>>> clue,
>>>>> please, post here.
>>>>>
>>>>> Thanks a lot.
>>>>>
>>>>>   
>>>>>       
>>>>>           
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
>>>> For additional commands, e-mail: c-dev-help@xerces.apache.org
>>>>
>>>>
>>>>
>>>>     
>>>>         
>>>   
>>>       
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
>> For additional commands, e-mail: c-dev-help@xerces.apache.org
>>
>>
>>
>>     
>
>   


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


Mime
View raw message