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();
}
}