Skip to content

All/bugfix/unst 9861 xmltree memory leaks#815

Open
harmenwierenga wants to merge 2 commits intomainfrom
all/bugfix/UNST-9861_xmltree_memory_leaks
Open

All/bugfix/unst 9861 xmltree memory leaks#815
harmenwierenga wants to merge 2 commits intomainfrom
all/bugfix/UNST-9861_xmltree_memory_leaks

Conversation

@harmenwierenga
Copy link
Copy Markdown
Contributor

What was done

  • Fix small issue where inquire accesses trailing whitespace in Fortran code
  • Update Dimr::GetInstance to use proper singleton pattern with static local variable instead of an allocated instance that is never deallocated
  • Only delete Dimr::log when it owns it, not when it refers to the DimrExe::log
  • Inside xmltree, use std::string over allocated char*. Make the fields private that can be private.
  • Delete log before deleting clock, since log references clock.
  • Fix bug where workingDir was assigned to a pointer to pointer cast to a char * (garbage): newComp->workingDir = (char*)&curPath;
  • Make workingDir an owned and allocated char *, so that it can always be deleted safely
  • Free the components[i].processes, which were leaking
  • Free the computeTimes when allocated, and ensure that they are nullptr otherwise. We cannot easily use a managed type, because dimr_control_block is always malloced.
  • Store the charDataStr (xmltree) in a state variable of the library, instead of in global data, so that there is no global std::string with constructors/destructors that can cause issues
  • Properly delete all children of the XML nodes

Evidence of the work done

  • Video/figures
    <add video/figures if applicable>
  • Clear from the issue description
  • Not applicable

Tests

  • Tests updated
    <add testcase numbers if applicable, Issue number>
  • Not applicable

Documentation

  • Documentation updated
    <add description of changes if applicable, Issue number>
  • Not applicable

Issue link UNST-9861

Copy link
Copy Markdown
Contributor

@adrimourits adrimourits left a comment

Choose a reason for hiding this comment

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

Nice!

Copy link
Copy Markdown
Contributor

@KoenBussemakerDeltares KoenBussemakerDeltares left a comment

Choose a reason for hiding this comment

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

I left a few remarks. Nice improvements in general!

freeLibs();

log->Write(DEBUG, my_rank, "dimr shutting down normally");
if (logIsOwned)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do you want to do this conditionally? Shutdown is happening normally even when the log is not owned.


if (logIsOwned)
{
delete log;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider a std::unique_ptr to store the logger instance. You can use it to check for ownership by testing against null, and you don't have to worry about cleanup.

for (int i = 0; i < rootXml->children.size(); i++)
{
if (strcmp(rootXml->children[i]->name, "component") == 0)
if (rootXml->children[i]->name == "component")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is incorrect, == will do a pointer comparison in this case (name is a char*, and the string literal will resolve to one as well). Use strcmp or put std::string("component") on the right hand side to trigger the use of std::string's equality operator.

If you want to be bold you can try changing the name from a char to a std::string, but you might just get into more trouble.

There are many other places where this happens too, make sure you check thoroughly.

rawWorkingDir = workingDirElement->charData.c_str();
}
// Is workingDir a valid relative path?
char* combinedPath = new char[MAXSTRING];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider using std::filesystem to fix this messy path handling. I also understand if you want to limit the scope of this PR, it is up to you.

this->charData = SubstEnvVar(this->charData);
}

for (int i = 0; i < children.size(); i++)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file is an excellent reminder why we should not write our own xml parsers


this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
const std::string& ppn = (parent == NULL) ? std::string() : parent->pathname;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If somebody ever has to remove the const it will lead to a dangling reference. I know this is guaranteed to work in it's current form, but IMO it's better to just make it a copy for clarity sake.

struct ParseState
{
XmlTree** curnode;
std::string charDataStr;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't use the type in the name

(*curnode)->charData[len] = '\0';
(*curnode)->charDataLen = len + 1;
CharDataLen = 0;
// Trim leading whitespace
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't there a nice boost function that can do this?

remainder = (char*)"";
else
*remainder++ = '\0';
std::string path = pathname;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Again, consider using std::filesystem for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants