Generated code can lead to memory leaks (C++)

Questions regarding the use of UaModeler

Moderator: uamodeler

Post Reply
LambertD
Hero Member
Hero Member
Posts: 22
Joined: 25 Jun 2014, 07:49

Generated code can lead to memory leaks (C++)

Post by LambertD »

Hello all,

I am using uamodeler 1.5.0 with c++ code generation templates version 1.5.0 (version 4)
We have some unit test that do certain manipulations of address spaces in single threaded and in multithreaded fashion.
When running the tests under valgrind it turns out they sometimes have memory leaks, especially the multithreaded ones.

After some investigation these problems could be traced back to the fact that the generated code, when instantiating nodes, does not check the status code (return value) of calls to addNodeAndReference on the node manager.
The thing here is: if such calls fail then the ownership of the node has not been moved to the nodemanager and the class that created the node has the responsibility to eventually call releaseReference on the node. I was able to demonstrate this by manually fixing the generated code and running the unit tests again.

So to be a little more specific, the generated code I am talking about here is code such as this:

Code: Select all

void FooTypeBase::initialize()
{
    OpcUa_Int16 nsIdx = m_pNodeConfig->getNameSpaceIndex();
    UaStatus      addStatus;
    UaVariant     defaultValue;

    if ( s_typeNodesCreated == false )
    {
        createTypes();
    }
    // Mandatory variable CustomField1
    m_pCustomField1 = new OpcUa::PropertyType(this, s_pCustomField1, m_pNodeConfig, m_pSharedMutex);
    addStatus = m_pNodeConfig->addNodeAndReference(this, m_pCustomField1, OpcUaId_HasProperty);
    UA_ASSERT(addStatus.isGood());

    // Mandatory variable CustomField2
    m_pCustomField2 = new OpcUa::PropertyType(this, s_pCustomField2, m_pNodeConfig, m_pSharedMutex);
    addStatus = m_pNodeConfig->addNodeAndReference(this, m_pCustomField2, OpcUaId_HasProperty);
    UA_ASSERT(addStatus.isGood());

You can see here that this code only UA_ASSERTS that the status of node and reference adding has succeeded, but this is does not work in release builds where that asserts are switched off. Fixing this type of code to check for the status and calling releaseReference() on the created nodes fixed the memory leaks.

There seems to be no other way to clean up nodes that could not be added to the address space, other than fixing the generated code. We have attempted to create a cleanup method that searches the address space to remove such "dangling nodes" but we haven't found a way and perhaps it is impossible.

So my question is, could you please, in some newer version of the uamodeler, update the templates such that these error codes are handled and nodes are eventually cleaned up ?

A suggestion I have for this is to, for every created class, keep flags around that indicate if the original addition of the node failed or succeeded, then in the destructor, check for every subnode if the original addition failed and release the reference in that case. This will still lead to a badly functioning address space, but at least the memory leaks will be dealt with. I would also suggest to have getters for every subnode flag so that calling code can detect that object creating did not fully succeed and can do extra error handling. Then something like an isValid method would be needed also that returns false if any of the subnode addition failed.

I hope I have stated my problem clear enough, if you have any more questions, please reply and please consider improving the generated code templates.

Kind regards,

Lambert Duijst

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re: Generated code can lead to memory leaks (C++)

Post by Support Team »

Than you for reporting this issue. We are discussing solutions to avoid these memory leaks.
The memory leak is caused by newly created Objects with NodeIds that are already used within the NodeManager. If the NodeManager takes care about the used NodeId identifiers for new nodes, there will not be a memory leak.
Best regards
Unified Automation Support Team

Post Reply