Jump to content

[SOLVED] Adding XML child causes crash on changing worlds


photo

Recommended Posts

Hello,

 

We ran into a funny bug after adding some XML processing. Using Xml.addChild in certain ways will cause the application to crash when changing the world. Here are some examples

//non-crashing method
Xml xml2 = xml1.addChild("Markup");
		
//any of the following will crash
Xml xml2 = new Xml("Markup");
xml1.addChild(xml2);
xml1.addChild(new Xml());
xml1.addChild(new Xml("Language"));

//these will also crash
Xml xml2 = xml1.addChild(new Xml());
Xml xml2 = xml1.addChild(new Xml("Language"));

And here is the error from our main project

19:17:03 Xml::do_parse(): bad xml close tag "</parameter>" must be "</get>"
19:17:03 Xml::load(): can't load "core/systems/tracker/parameters/node.parameters" file
19:17:03 Unigine::Tracker::Tracker::loadParameters(): can't open "core/systems/tracker/parameters/node.parameters" file

We dug into the crash a little bit and in XmlParser.cpp in Unigine source, Xml::do_parse was presenting some memory allocation problems in this code block starting on line 353

Xml *xml = new Xml();
xml->currentLine = currentLine;
s += xml->do_parse(s);
currentLine = xml->currentLine;
addChild(xml);

When it's creating a new Xml object, FixedPool's allocation is causing it to overwrite the parent's memory location. We aren't totally sure why or how, that's as far as we got today.

 

I am attaching a sample project and we get a crash error but not the same message. We haven't debugged the sample project but it should be useful.

 

Thanks,

Taylor

 

 

 

(I had to delete QT to get sample project filesize under limit so editor probably doesn't work)

XMLChilds.zip

Link to comment
  • 2 weeks later...

Hi there, Taylor!

 

I'm not sure if it's a bug but it's definitely very unclear behaviour. The problem is that Xml internally will delete all children and so will do the script that owns Xml variables. That means, by this code:

// Case 1
Xml xml1 = new Xml("Extensible");
Xml xml2 = new Xml("Markup");
xml1.addChild(xml2);

// Case 2
Xml xml1 = new Xml("Extensible");
xml1.addChild(new Xml());
xml1.addChild(new Xml("Language"));

You'll get two owners: one is root Xml class and second is script variable.

 

The solution is to release the ownership of script variable by using class_remove function. More info about ownership and memory management: https://developer.unigine.com/en/docs/2.1.1/code/memory_management#script.

 

Here's fixed code with proper ownership:

// Case 1
Xml xml1 = new Xml("Extensible");
Xml xml2 = class_remove(new Xml("Markup"));
xml1.addChild(xml2);

// Case 2
Xml xml1 = new Xml("Extensible");
xml1.addChild(class_remove(new Xml()));
xml1.addChild(class_remove(new Xml("Language")));

The same logic goes for Json class.

Link to comment
×
×
  • Create New...