Skip to content

Fix xmlLoadString memory leak #1531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 23, 2020
Merged

Conversation

Lpsd
Copy link
Member

@Lpsd Lpsd commented Jun 20, 2020

Resolves #1373

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, mate.

@StrixG StrixG added the bug Something isn't working label Jun 20, 2020
@StrixG StrixG added this to the 1.5.8 milestone Jun 20, 2020
@qaisjp
Copy link
Contributor

qaisjp commented Jun 20, 2020

Possible to incorporate smart pointers?

@Pirulax
Copy link
Contributor

Pirulax commented Jun 20, 2020

Well, kinda? But I woudn't, because it woudnt be proper use of them IMHO. Lua itself won't hold the reference count up, so its kinda mix and match.

@Lpsd
Copy link
Member Author

Lpsd commented Jun 20, 2020

Possible to incorporate smart pointers?

I'd have to actually learn about smart pointers - eek!

If someone else wants to add that to this PR very, very soon then go ahead - otherwise I think we should just merge as is (1.5.8 overdue!)

@ghost
Copy link

ghost commented Jun 20, 2020

Does this really fix the memory leak? The memory gets freed when the destructor of CLuaMain is called, and CLuaMain is only called when the client exits the server. So if the client never leaves the server, then the memory will keep on stacking up.

@Lpsd
Copy link
Member Author

Lpsd commented Jun 20, 2020

I monitored the memory usage on both the client and server using the following script (edit: just added an updated version which appears to work the same)

local xml = {}
local instances = 10000

function xmlStringTest()
	for i=1, instances do
		xml[#xml+1] = xmlLoadString("<animals><animal type='monkey'></animal></animals>")
	end
end
addCommandHandler(triggerClientEvent and "sxml" or "cxml", xmlStringTest)

When restarting/stopping the resource, the memory is freed on both client and server (and freed for the client when leaving the server). I guess one thing I didn't think of is how you can free the memory from Lua without needing to restart/stop the resource.

In that case do we need to add a function such as xmlUnloadString?

@ghost
Copy link

ghost commented Jun 20, 2020

I see. CLuaMain is per resource.

In that case do we need to add a function such as xmlUnloadString?

I think extending xmlUnloadFile to support unloading of loaded strings would be nice.

@Lpsd
Copy link
Member Author

Lpsd commented Jun 20, 2020

Would it not make more sense (naming wise) to create xmlUnload which supports nodes created via xmlLoadString and xmlLoadFile (and optionally deprecate/add warning for xmlUnloadFile)

@ghost
Copy link

ghost commented Jun 20, 2020

Would it not make more sense (naming wise) to create xmlUnload which supports nodes created via xmlLoadString and xmlLoadFile (and optionally deprecate/add warning for xmlUnloadFile)

Technically, a loaded string is also a file. To be honest, I would've just added an extra optional paramter to xmlLoadFile for loading xml files as strings, but now since we have a function, I don't think it matters that much if we use xmlUnloadFile for unloading xml files that were loaded as strings.

@qaisjp
Copy link
Contributor

qaisjp commented Jun 20, 2020

For what it's worth @saml1er I'd argue we can still remove xmlLoadString and replace with xmlLoadFile as it's a beta function and not officially released yet.

@ghost
Copy link

ghost commented Jun 20, 2020

For what it's worth @saml1er I'd argue we can still remove xmlLoadString and replace with xmlLoadFile as it's a beta function and not officially released yet.

That makes sense. We haven't officially released it. We can remove xmlLoadString and extend xmlLoadFile.

@qaisjp
Copy link
Contributor

qaisjp commented Jun 21, 2020

To be honest, I would've just added an extra optional paramter to xmlLoadFile for loading xml files as strings

Possible to keep it consistent with other functions (e.g. engineLoadTXD/playSound/dxCreateShader) and use a heuristic?

The first two examples above are binary but this is the heuristic used for dxCreateShader:

bool bIsRawData = false;
const bool bValidFilePath = CResourceManager::ParseResourcePathInput(strFile, pFileResource, &strPath, &strMetaPath);
if (!bValidFilePath || (strFile[0] != '@' && strFile[0] != ':'))
{
bIsRawData = strFile.find("\n") != std::string::npos;
if (!bIsRawData)
{
bIsRawData = (strFile.find("technique ") != std::string::npos) && (strFile.find("pass ") != std::string::npos) &&
(strFile.find('{') != std::string::npos) && (strFile.find('}') != std::string::npos);
}
}

Perhaps if it satisfies any of the following properties:

  • contains \n, OR
  • contains two < and two >, OR
  • contains < and />

Maybe a heuristic is a bad idea in this case, since on Linux, < and > are perfectly valid filename characters.

@Pirulax
Copy link
Contributor

Pirulax commented Jun 21, 2020

If it's longer than 256 characters it must raw data*. If that fails, check for other things, that'd be the fastest IMHO

*Well, kinda. Windows now supports more than 256 afaik, but, nobody uses more than that.

@Lpsd
Copy link
Member Author

Lpsd commented Jun 22, 2020

We would need to use existing MTA file functions to verify the path/file exists and is a valid resource file.

Character length and/or checking included characters isn't good enough in this situation.

@Lpsd
Copy link
Member Author

Lpsd commented Jun 23, 2020

The suggested changes have deviated too much from what the initial PR intended to do - I'll close this and submit a new PR soon which re-implements XML string loading into xmlLoadFile (and removes xmlLoadString)

@Lpsd Lpsd closed this Jun 23, 2020
@qaisjp
Copy link
Contributor

qaisjp commented Jun 23, 2020

I mean, we can merge this (once it uses smart pointers), and you can do the xmlLoadFile/xmlLoadString merge in a separate PR. That way there's one PR for the bugfix and a separate PR for the refactor.

(If you prefer to do it in one PR, please use separate commits for the bugfix and the refactor.)

@qaisjp qaisjp reopened this Jul 7, 2020
@qaisjp
Copy link
Contributor

qaisjp commented Jul 23, 2020

I'm happy to just let this one through in favour of getting this fixed ASAP. This is due a refactor anyway

@qaisjp qaisjp merged commit 93b10c3 into multitheftauto:master Jul 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

xmlLoadString has memory leaks
4 participants