Why doesn't tinyxml2 want to load my file?

Started by
3 comments, last by SeanMiddleditch 7 years, 4 months ago

I'm trying to load a simple XML file using TinyXml2 but it just crashes.

This is the contents of the file I'm trying to load :


<Texture Name='Grass' Path='Data/Textures/Grass.png'> </Texture>

My file structure looks like this :

6349dab3e1cb314c0492a96a84c3b303.png

Here's how I'm attempting to load the file :


XMLFile file;
file.LoadFile("Data/Textures/textures.xml");

XMLFile::LoadFile() is this :


bool XMLFile::LoadFile(const std::string& filePath)
{
	if (mDocument->LoadFile(filePath.c_str()) != XML_SUCCESS)
	{
		gDebugger.PrintError(__FILE__, "Failed to load file : " + filePath + " from disk.");
		return false;
	}

	return true;
}

mDocument is this in the header file :


tinyxml2::XMLDocument* mDocument;

It tells me that it crashed in tinyxml2.cpp on line 765 :


void XMLNode::DeleteChildren()
{
    while( _firstChild ) { /* Crashes here */
        TIXMLASSERT( _lastChild );
        DeleteChild( _firstChild );
    }
    _firstChild = _lastChild = 0;
}

I can't understand what I'm doing wrong? :/

Advertisement

Are the functions you posted the actual callstack? What are the line numbers? As presented, it sounds like you've just found a bug, but the DeleteChildren call isn't something I'd expect to be called during Load (though maybe it is in the error case). If it is the load, it may be that tinyxml doens't like using single quotes. Tinyxml seems to have only a couple simplistic test cases and none of them use single quotes.

A library should never crash because of simple user error, so unless it turns out that that you're doing something naughty in code that you haven't posted, I'd go to tinyxml's issue tracker is at https://github.com/leethomason/tinyxml2/issues and file a bug with the complete callstack and example code / data file that repros the crash.

Sean Middleditch – Game Systems Engineer – Join my team!

Did you remember to create a new `tinyxml2::XMLDocument` before attempting to load the file from disk? Crashing at the first attempt to read a member variable is a symptom of using an invalid object, see this example, http://ideone.com/5YE0I4:

class Foobar {
public:
	Foobar(int x) : x(x) {
	}

	void frobnicate_1() {
		cout << "In frobnicate_1, this=" << this << endl;
	}

	void frobnicate_2() {
		cout << "In frobnicate_2, this=" << this
			 << ", y=" << Foobar::y  // doesn’t lookup “this”
			 << ", x=" << flush;

		cout << this->x << endl;  // crash, if “this” isn’t valid
	}
private:
	int x;
	static int y;
};

int Foobar::y = -3;


int main() {
	Foobar a(5);

	Foobar* f = &a;
	f->frobnicate_1();
	f->frobnicate_2();

	f = nullptr;
	f->frobnicate_1();
	f->frobnicate_2(); // crash!
}

Output:

In frobnicate_1, this=0xff88ff1c
In frobnicate_2, this=0xff88ff1c, y=-3, x=5
In frobnicate_1, this=0
In frobnicate_2, this=0, y=-3, x=

Runtime error!

Did you remember to create a new `tinyxml2::XMLDocument` before attempting to load the file from disk? Crashing at the first attempt to read a member variable is a symptom of using an invalid object, see this example, http://ideone.com/5YE0I4:


class Foobar {
public:
	Foobar(int x) : x(x) {
	}

	void frobnicate_1() {
		cout << "In frobnicate_1, this=" << this << endl;
	}

	void frobnicate_2() {
		cout << "In frobnicate_2, this=" << this
			 << ", y=" << Foobar::y  // doesn’t lookup “this”
			 << ", x=" << flush;

		cout << this->x << endl;  // crash, if “this” isn’t valid
	}
private:
	int x;
	static int y;
};

int Foobar::y = -3;


int main() {
	Foobar a(5);

	Foobar* f = &a;
	f->frobnicate_1();
	f->frobnicate_2();

	f = nullptr;
	f->frobnicate_1();
	f->frobnicate_2(); // crash!
}

Output:

In frobnicate_1, this=0xff88ff1c
In frobnicate_2, this=0xff88ff1c, y=-3, x=5
In frobnicate_1, this=0
In frobnicate_2, this=0, y=-3, x=

Runtime error!

Forgot to create the XMLDocument before using it, why do I never notice this :(

Are the functions you posted the actual callstack? What are the line numbers? As presented, it sounds like you've just found a bug, but the DeleteChildren call isn't something I'd expect to be called during Load (though maybe it is in the error case). If it is the load, it may be that tinyxml doens't like using single quotes. Tinyxml seems to have only a couple simplistic test cases and none of them use single quotes.

A library should never crash because of simple user error, so unless it turns out that that you're doing something naughty in code that you haven't posted, I'd go to tinyxml's issue tracker is at https://github.com/leethomason/tinyxml2/issues and file a bug with the complete callstack and example code / data file that repros the crash.

Does "forgetting to call new on the XMLDocument before using it" count as a simple user error? :P

Does "forgetting to call new on the XMLDocument before using it" count as a simple user error?

Yes. Yes it does. :)

Of course, this is why pointer-based APIs are bad juju, but that's another topic... ;)

Sean Middleditch – Game Systems Engineer – Join my team!

This topic is closed to new replies.

Advertisement