Skip to content

objectRegistry::readModifiedObjects segfaults with collated file handler

Summary

When using the collated file handler, if a non-collated regIOobject gets re-read by the objectRegistry::readModifiedObjects, OpenFOAM sometimes segfaults because the iterator object is pointing to freed memory.

In the following function:

void Foam::objectRegistry::readModifiedObjects()
{
    for (iterator iter = begin(); iter != end(); ++iter)
    {
        if (objectRegistry::debug)
        {
            Pout<< "objectRegistry::readModifiedObjects() : "
                << name() << " : Considering reading object "
                << iter.key() << endl;
        }

        iter.val()->readIfModified();
    }
}

The readIfModified of a regIOobject causes the regIOobject to be checked out and checked back in when using the collated file handler. This is caused by operator= which is called in masterUncollatedFileOperation::readStream function: https://develop.openfoam.com/Development/openfoam/-/blob/master/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C#L1939 However, the iterator is still pointing at the memory location of the old HashTablePair of the checked out regIOobject. Because of this, when calling the increment function of the iterator, the next_ pointer is the next_ of the old HashTablePair which has been deleted already, and so sometimes the value of next_ will be garbage, and when it gets dereferenced a segfault happens.

Either the regIOobject should not be checked out and checked back in, or some different handling should be done with the iterator.

Steps to reproduce

An example would be to use the timeActivatedFileUpdate to cause a solver to re-read the fvSolution file. When the fvSolution gets re-read, sometimes OpenFOAM will segfault (it does not happen every time since sometimes the old freed memory is still in "a good state").

What is the current bug behaviour?

OpenFOAM reads freed memory which sometimes causes a segfault.

What is the expected correct behavior?

OpenFOAM should not read freed memory.

Environment information

  • OpenFOAM version :v2306
  • Operating system :centos
  • Compiler :gcc 12.2.0

Possible fixes

This is a possible workaround even though I think the real issue is the checking out and checking back in of the regIOobject in the masterUncollatedFileOperation::readStream function:

void Foam::objectRegistry::readModifiedObjects()
{
    iterator iter = begin();
    while (iter != end())
    {
        if (objectRegistry::debug)
        {
            Pout<< "objectRegistry::readModifiedObjects() : "
                << name() << " : Considering reading object "
                << iter.key() << endl;
        }

        regIOobject* currentObjPtr = iter.val();
        // Increment iterator before potentially changing the entry in the table
        ++iter;

        currentObjPtr->readIfModified();
    }
}