Pergunta

Eu fui brincar com a Xerces-C biblioteca XML.

Eu tenho este exemplo simples que eu estou jogando com ele.

Eu não consigo fazê-lo funcionar sem vazamento de memória e sem segfaulting. É um ou o outro.

O segfault ocorre sempre quando eu excluir o objeto parser em "Clean up".

Eu tentei usar ambos os 2.8 e 2.7 versões da biblioteca.

Nota: I levou todos a exceção check-out do código, eu obter os mesmos resultados com ele e sem ele. Para facilitar a leitura e simplicidade Tirei-o do código abaixo.

pessoas Quaisquer Xerces-savvy lá fora importo de fazer algumas sugestões?

Eu não posso realmente dizer muito do traço de volta, é só saltar para dentro do destructor superclasse e segfaulting lá.

Backtrace:

(gdb) bt
#0  0x9618ae42 in __kill ()
#1  0x9618ae34 in kill$UNIX2003 ()
#2  0x961fd23a in raise ()
#3  0x96209679 in abort ()
#4  0x95c5c005 in __gnu_cxx::__verbose_terminate_handler ()
#5  0x95c5a10c in __gxx_personality_v0 ()
#6  0x95c5a14b in std::terminate ()
#7  0x95c5a6da in __cxa_pure_virtual ()
#8  0x003e923e in xercesc_2_8::AbstractDOMParser::cleanUp ()
#9  0x003ead2a in xercesc_2_8::AbstractDOMParser::~AbstractDOMParser ()
#10 0x0057022d in xercesc_2_8::XercesDOMParser::~XercesDOMParser ()
#11 0x000026c9 in main (argc=2, argv=0xbffff460) at test.C:77

O código:

#include <string>
#include <vector> 

#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif

#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>

using namespace std;

XERCES_CPP_NAMESPACE_USE

int main(int argc, char const* argv[])
{

  string skXmlMetadata = "<?xml version=\"1.0\"?>\n <xmlMetadata>b</xmlMetadata>";

  XMLPlatformUtils::Initialize();
  XercesDOMParser* xmlParser = NULL;
  DOMWriter* xmlWriter = NULL; 
  ErrorHandler* errHandler = NULL;
  const XMLByte* xmlBuf =  NULL;
  MemBufInputSource* memBufIS = NULL;
  DOMNode* xmlDoc = NULL;

  xmlParser = new XercesDOMParser();
  xmlParser->setValidationScheme( XercesDOMParser::Val_Never );
  xmlParser->setDoNamespaces( false );
  xmlParser->setDoSchema( false );
  xmlParser->setLoadExternalDTD( false );

  errHandler = (ErrorHandler*) new HandlerBase();
  xmlParser->setErrorHandler( errHandler );

  // Create buffer for current xmlMetadata
  xmlBuf = (const XMLByte*) skXmlMetadata.c_str();
  const char* bufID = "XmlMetadata";
  memBufIS = new MemBufInputSource( xmlBuf, skXmlMetadata.length(), bufID, false );

  // Parse
  xmlParser->resetErrors();
  xmlParser->parse( *memBufIS );
  xmlDoc = xmlParser->getDocument();

  // Write created xml to input SkArray
  XMLCh* metadata = NULL;
  xmlWriter = DOMImplementation::getImplementation()->createDOMWriter();
  xmlWriter->setFeature( XMLUni::fgDOMWRTFormatPrettyPrint, true );
  metadata = xmlWriter->writeToString( *xmlDoc );
  xmlWriter->release();


  // Print out our parsed document
  char* xmlMetadata = XMLString::transcode( metadata );
  string c = xmlMetadata;
  cout << c << endl;

  // Clean up
  XMLString::release( &xmlMetadata );
  xmlDoc->release();
  delete xmlParser; // Dies here
  delete memBufIS;
  delete errHandler;
  XMLPlatformUtils::Terminate();

  return 0;
}
Foi útil?

Solução

"xmlDoc-> Release ();" é o culpado. Você não própria que Node menos que você diga "xmlParser-> adoptDocument ()"

http://xerces.apache.org/xerces -c / apidocs-2 / classAbstractDOMParser.html # fe052561c37d70b62ac57ab6706d75aa

Outras dicas

Permite explorar a evidência ...

#6  0x95c5a14b in std::terminate ()

Eu posso dizer-lhe isto é chamado quando um destruidor lança uma exceção. Destruidores lançar exceções é um grande não-não. Xerces pode estar fazendo algo instável.

Ou pode ser causada por esta linha

#7  0x95c5a6da in __cxa_pure_virtual ()

onde algo pode estar faltando em uma tabela de função virtual. Talvez um dos membros destruidor do objeto DOM? Talvez isso gera uma exceção?

Este link oferece uma grande explicação sobre o que poderia fazer com que as pesquisas de tabela virtuais para falhou. Em suma, pode ser causada por uma pendendo da classe base ponteiro pendurado em torno de alguém tentando fazer uma chamada de função polimórfica sobre esse ponteiro.

Exemplo dada da ligação acima:

// From sample program 5:
AbstractShape* p1 = new Rectangle(width, height, valuePerSquareUnit);
std::cout << "value = " << p1->value() << std::endl;
AbstractShape* p2 = p1;  // Need another copy of the pointer.
delete p1;
std::cout << "now value = " << p2->value() << std::endl;

Falando de ponteiros pendurados, parece que o XercesDomParser está segurando objetos que você newed:

  errHandler = (ErrorHandler*) new HandlerBase();
  xmlParser->setErrorHandler( errHandler )

mas depois apagou / liberado

  // Clean up
  XMLString::release( &xmlMetadata );
  xmlDoc->release();
  delete xmlParser;
  delete memBufIS;
  delete errHandler;

Será que a ordem você está destruindo coisas estar incorreta e causar algum dos problemas acima? Em face disso, as coisas parecem OK, mas que é onde eu iria experimentar e verifique a documentação sobre como as coisas devem ser demolido.

Não consigo ver nada de errado, obviamente com o código. Você pode tentar remover todos os usos de novo e excluir o código e criar as Cerces objetos que você usar como objectys baseado em pilha vez. Por exemplo, em vez de:

xmlParser = new XercesDOMParser();

uso:

XercesDOMParser xmlParser;

e assim por diante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top