Newbie Segfault Issue

M

mearvk

A good bit of it is commented out so pay attention. I get a seg fault
(just says Segmentation Fault) when trying to run this with the line
below uncommented. I'm a java programmer so excuse the clumniness of
the code; it's still very early in development.

This line seems to be the culprit, but I'm not sure why:
document->getElementsByTagName(targetNodes); std::cout<<"7";



Help appreciated,

Max

[START SOURCE]

#include <string.h>
#include <iostream>

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMNodeIterator.hpp>
#include <xercesc/dom/DOMNodeList.hpp>
#include <xercesc/dom/DOMText.hpp>


#include "DDAS_XML_Parser.h"

XERCES_CPP_NAMESPACE_USE

int main(int argc, char* argv[])
{
try
{
//XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch)
{
// Do your failure processing here
//return 1;
}

// Do your actual work with Xerces-C++ here.
std::string fileURL="results.xml";
int* defNums=getDefinitionNumbers(fileURL.c_str());

//Terminate DDAS_XML_Parser
//XMLPlatformUtils::Terminate();

// Other terminations and cleanup.

return 0;
}

void echo(const char* e)
{
std::cout<<e;
}

int* getDefinitionNumbers(const char* file_URL)
{

try
{
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch)
{
char* message =
XMLString::transcode(toCatch.getMessage());
std::cerr<<"ERROR:"<<message<<"."<<std::endl;
XMLString::release(&message);
}

std::cout<<"1";


XercesDOMParser* parser = new XercesDOMParser();

parser->setValidationScheme(XercesDOMParser::Val_Auto);
parser->setDoNamespaces(false);
parser->setDoSchema(false);
parser->setLoadExternalDTD(false);


std::cout<<"2";


//DOMDocument* document;
//DOMElement * rootNode;
//DOMNodeList* nodeList;

XMLCh* targetNodes = XMLString::transcode("dataRow");
XMLCh* targetAttrs = XMLString::transcode("defNumber");

try
{
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch)
{
char* message =
XMLString::transcode(toCatch.getMessage());
std::cerr<<"ERROR:"<<message<<"."<<std::endl;
XMLString::release(&message);
}

std::cout<<"3";

try
{
parser->parse(file_URL);
std::cout<<"4";
DOMDocument* document=parser-
getDocument(); std::cout<<"5";
DOMElement* rootNode=document-
getDocumentElement(); std::cout<<"6";
//document->getElementsByTagName(targetNodes);
std::cout<<"7";
}
catch(const XMLException& toCatch)
{
char* message =
XMLString::transcode(toCatch.getMessage());
std::cerr<<"ERROR:"<<message<<"."<<std::endl;
XMLString::release(&message);

}

//CLEAN UP
//delete parser;
XMLPlatformUtils::Terminate();

return NULL;
}

/*
*
* g++ -c DDAS_XML_Parser.C
* g++ -L/usr/src/xerces-c-src_2_8_0/lib -lxerces-c
DDAS_XML_Parser.o -o test
*
*
*/
[STOP SOURCE]
 
B

Brian Szmyd

A good bit of it is commented out so pay attention. I get a seg fault
(just says Segmentation Fault) when trying to run this with the line
below uncommented. I'm a java programmer so excuse the clumniness of the
code; it's still very early in development.

This line seems to be the culprit, but I'm not sure why:
document->getElementsByTagName(targetNodes); std::cout<<"7";



Help appreciated,

Max

I don't know anything about Xerces, by why are you calling this twice?
XMLPlatformUtils::Initialize()

Anyways, there are only two reasons that the code would segfault on:

document->getElementsByTagName(targetNodes);

1.) document is not a valid pointer to a DOMDocument object. But since
the line before it seems to work, then I have to assume that it is valid.

2.) targetNodes is not valid, meaning it's either undersized or an
invalid XMLCh pointer. Since this is the first use of it that I can see I
have to guess that this is the correct answer.

Try doing this:

XMLCh* targetNodes = NULL;
if ( ! ( targetNodes = XMLString::trans... ) ) std::cout << "Invalid
XMLCh assignment to targetNodes";
....
DOMDocument* document = NULL;
if ( ! ( document = parser->... ) ) std::cout << "Invalid DOMDocument
assignment to document";

and see if you get anything. Otherwise might I suggest using gdb on the
core file it creates?
 
R

Richard James

mearvk said:
A good bit of it is commented out so pay attention. I get a seg fault
(just says Segmentation Fault) when trying to run this with the line
below uncommented. I'm a java programmer so excuse the clumniness of
the code; it's still very early in development.

This line seems to be the culprit, but I'm not sure why:
document->getElementsByTagName(targetNodes); std::cout<<"7";

Are you sure because I thought that cout was buffered and it needs to be
flushed after each usage when used for debugging programs, otherwise you
will not get the full output, the program crashes before the entire buffer
is flushed.

Anyway I thought I would have a look at your code (not being real good at
c++ and all) and see if I could find any error.

I could not it all seems valid. So then I had a look at xerces site and
found this section.
http://xerces.apache.org/xerces-c/faq-parse.html#faq-7

I'm suddenly getting segfaults with Xerces-C 2.3.0; why might this be?

The introduction of pluggable memory management into Xerces-C, one of the
main features of 2.3.0, means that application writers have to be more
conscious about destructors being invoked implicitly after a call to
XMLPlatformUtils::Terminate(). For example, the following code is
guaranteed to produce a segmentation fault under Xerces-C 2.3.0, while it
happened to work under previous versions (in fact, this was how our
SAXPrint sample was formerly written; try-catch blocks removed for
brevity):


void myParsingFunction()
{
XMLPlatformUtils::Initialize();
SAXParser parser;
//parser.various method calls
XMLPlatformUtils::Terminate();
} // seg fault here!


The reason this will produce a segmentation fault is that any dynamic memory
the SAXParser (or any other of Xerces's parsers) needs to allocate is now
allocated by default by a static object owned by XMLPlatformUtils. When the
XMLPlatformUtils::Terminate() call is made, this object is destroyed--and,
consequently, so are all the objects that it directly created. This
includes all the objects dynamically allocated by the SAXParser. When the
parser object goes out of scope, its destructor is invoked, and this
attempts to destroy all the objects that it created--which have of course
just been destroyed by the static MemoryManager in XMLPlatformUtils.

To avoid this, one must either explicitly scope the parser object inside
calls to XMLPlatformUtils::Initialize() and XMLPlatformUtils::Terminate(),
or dynamically allocate the parser object and destroy it explicitly before
the call to XMLPlatformUtils::Terminate() is made.

Another way of producing segmentation faults--that again, unfortunately, was
employed by some of our samples--is to have calls to
XMLPlatformUtils::Terminate() in a catch block that catches any of Xerces's
exceptions. Since the destructor of the exception will implicitly be
invoked upon exit from the catch block, and since some of the exceptions'
destructors call on Xerces's default memory manager to destroy
dynamically-allocated objects, their destruction will provoke a
segmentation fault even if a return statement is placed in the catch block
since the default memory manager will no longer exist. This practice is now
avoided in all our samples.

*********************************************************************

So Basically what it is saying is that

Before you call XMLPlatformUtils::Terminate()
make sure the parser object is destroyed/deleted.

How do you do this? I don't really know but my first thought would be to put
the parser in a code block like this.
XMLPlatformUtils::Initialize();
{
XercesDOMParser* parser = new XercesDOMParser();

parser->setValidationScheme(XercesDOMParser::Val_Auto);
parser->setDoNamespaces(false);
parser->setDoSchema(false);
// etc etc
} // hopefully that should delete the parser
// all finished
XMLPlatformUtils::Terminate();

Richard James
 
R

Richard James

Richard said:
Are you sure because I thought that cout was buffered and it needs to be
flushed after each usage when used for debugging programs, otherwise you
will not get the full output, the program crashes before the entire buffer
is flushed.

Anyway I thought I would have a look at your code (not being real good at
c++ and all) and see if I could find any error.

I could not it all seems valid. So then I had a look at xerces site and
found this section.
http://xerces.apache.org/xerces-c/faq-parse.html#faq-7

I've just downloaded and installed xerces-c-src_2_8_0.tar.gz
on my Slackware 11 machine and compiled your code and it ran fine without
any changes but I was getting segfaults because I had no result.xml file in
the directory the program was being run from. So I copied another plain xml
file into that directory and the segfaults disappeared. Are you sure that
results.xml is in the same directory as you are executing that file.

i.e.
richard@wildfire:~/test$ ls results.xml
results.xml
richard@wildfire:~/test$ ./test
1234567richard@wildfire:~/test$ cd ..
richard@wildfire:~$ ./test/test
Segmentation fault
richard@wildfire:~$ ls results.xml
/bin/ls: results.xml: No such file or directory
richard@wildfire:~$

also use std::endl after each cout when debugging your code is
std::cout<<"7";
should be
std::cout<<"7"<<std::endl;

After doing this I run your program like this
richard@wildfire:~/test$ ls results.xml ; ./test
results.xml
1
2
3
4
5
6
7
richard@wildfire:~/test$ cd ..
richard@wildfire:~$ ls results.xml ; ./test/test
/bin/ls: results.xml: No such file or directory
1
2
3
4
5
Segmentation fault
richard@wildfire:~$

Richard James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top