TinyXML2 Segfault.

Started by
1 comment, last by Michael Lojkovic 7 years, 10 months ago

I'm building a binary tree based on the xml document I'm parsing with TinyXML2,(Is 3 the right name now?) so dialogue branches from documentation go into the engine correctly. I had an implementation of the initial tree that was almost working, but Nodes in the XML doc aren't sorted in the order they go in, and the Id for each value isn't in numerical order. A few of the dialogues ended up in the tree correctly, but it didn't work for every dialogue in the XML. Thus, I'm currently experimenting by looping through the document and dropping nodes in the order they should go for each dialogue. The only problem is after looping through a few times TinyXML causes a segfault.

The doc has two basic sections. Psuedocode for it is below.


<Content>
   <DialogueFragment Id="10">
     //..
   <DialogueFragment/>
   //...
</Content>

<Hierarchy>
  <Node Type="Dialogue" Id= "1">
    <Node Type="DialogueFragment" Id="10"/>
    <Node Type="Connection" Id="2"/>
  </Node>
</Hierarchy>

I'm starting with the top Dialogue with Id 1, and figuring out which DialogueFragment comes first, based on the Connection having Dialogue Id as the source and DialogueFragment Id 10 as the target. Then repeating that process for DialogueFragment Id 10 as the connection source, and so on till no more children are left. I tried just searching through the Hierarchy from top to bottom, for each Dialogue, but the only problem is when the documentation software generates XML the nodes aren't always listed in the correct order, and their numerical value doesn't indicate the order they go in.

My code is pretty messy right now, since I'm trying to figure out the correct algorithm for sorting nodes in the correct order, before adding them to my tree structure. Anyone know how to prevent the segfault caused by TinyXML2 when using FirstChildElement?

Advertisement

Anyone know how to prevent the segfault caused by TinyXML2 when using FirstChildElement?

While it certainly is possible there is a bug in the version of TinyXML2 you are using, it is more likely something else in either your usage of it, or something unrelated in your program destroying the state for TinyXML causing it to crash. (maybe because of a buffer overrun or invalid pointer, writing in memory it shouldn't write in, or just some mistake in usage of the API)

To know which of the possibilities is true, you need to debug the problem more.

Why exactly is FirstChildElement crashing? nullptrs? does the state look ok?

If some internal variable in TinyXML is broken, maybe put a watch on it before it breaks and see who changes it.

You should be able to loop through your document as many times as you please without it crashing.

So something is obviously going wrong, but more investigation is needed to know what.

This is the code that's causing issue: (Shortened for brevity)


c = content->FirstChildElement("Connection");
while(dialogues[0] != nullptr) // rewrite to iterate to the next dialogue
{
        if(c->FirstChildElement("Source")->Attribute("IdRef", rightTarget.front().c_str()))
	     connectionNodes.push_back(c);
	if(c != nullptr)
	     c = c->NextSiblingElement("Connection");

	if(c == nullptr)
	{

	     FindDialogueChildren(dialogues, connectionNodes, orderedNodes, sourceCount, childTypes);

	     c = content->FirstChildElement("Connection");
	     while(c != nullptr)
	     {
		   while(c != nullptr && !c->FirstChildElement("Source")->Attribute("IdRef", id.c_str()))
		   {
			c = c->NextSiblingElement("Connection");
		   }

		   if(c != nullptr)
		   {
			connectionNodes.push_back(c);
			c = c->NextSiblingElement("Connection");
		   }
	     }
             c = content->FirstChildElement("Connection');
	}
}

Right now, it's supposed to loop forever or until it crashes. Once I have all the nodes from the dialogue in there I'll worry about moving onto the next dialogue. What happens right now is it loops through this twice, and on the third loop segfaults when TinyXML2 is looping through the dialogue structure to find the first "Connections" node, from the start of the document.

I'm having a feeling it's from TinyXML's design to be light on memory that's causing a buffer overflow, after looping through the 3000 line document so many times. Just trying to look at what node->_next is in FirstChildElement() causes GDB to freak out causing a segfault, and spamming a bunch of lines in CLion. Prior to the crash node is pointing to a valid XML tag. This post on TinyXML++ seems to suggest a similar issue. (I get that it's slightly different)

I'm currently working on dropping all of the Connection nodes into a vector and looping through that with an iterator. Caused other issues, which I think I need to copy the Source and Target node of each connection into a pair, and loop through that.

This topic is closed to new replies.

Advertisement