View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001538 | OpenFOAM | Bug | public | 2015-02-17 17:25 | 2015-02-21 13:04 |
Reporter | wyldckat | Assigned To | henry | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Summary | 0001538: Undetected ill-formed list can lead PtrList to have a massive memory leak, due to infinite loop | ||||
Description | I found out about this when using topoSet, when I accidentally and incorrectly closed off the end of the actions list like this: actions ( ... }; This seems harmless enough, but unfortunately it even lead me to get the machine almost locked up for 30 minutes, while it was filling the swap and I was not able to abort the process (slow swap disk :(). The bug seems to be is in this piece of code at "src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C": token lastToken(is); while ( !( lastToken.isPunctuation() && lastToken.pToken() == token::END_LIST ) ) { is.putBack(lastToken); sllPtrs.append(inewt(is).ptr()); is >> lastToken; } When it reaches the last token on the token list/stream, it somewhat strangely gives the last token repeatedly, leading to the infinite loop. The suggested fix is in the "Additional Information" section. Further investigation into this lead me to the method "Foam::primitiveEntry::read", where it's parsing the opening and closure of blocks and lists regardless of their types. Nonetheless, trying to account for the two types separately will only avoid the first error triggered, but it would not avoid the second type of error, namely where the user might accidentally swap the list/block terminators, namely 4.b in the next section "Steps To Reproduce". | ||||
Steps To Reproduce | 1. Warning: Do not test this bug, without first running this command: ulimit -Sv 2000000 it will limit the amount of RAM allowed for each applications in the current shell. 2. Go to the tutorial "incompressible/simpleFoam/pipeCyclic". 3. Run "blockMesh". 4. Edit the file "system/topoSetDict" and change the end of the list from this: option any; } } ); to one of the following two possible-example combinations: a) option any; } } }; b) option any; } ) }; 5. Run "topoSet". If you did #1, then it should crash when it reaches the limit of 2GB of RAM. If you did not do #1, then hit Ctrl+C as soon as possible!!! | ||||
Additional Information | Possible fix: --- a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C +++ b/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C @@ -116,6 +116,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt) { is.putBack(lastToken); sllPtrs.append(inewt(is).ptr()); + is.getBack(lastToken); //flush lastToken is >> lastToken; } But this doesn't feel very correct. In fact, this feels very odd as it being a solution... but it worked for me (Ubuntu 12.04, GCC 4.6.3), since it forces to never have anything in the "putBack" buffer, albeit risky. | ||||
Tags | No tags attached. | ||||
|
This is an interesting problem. I have looked at various ways to avoid the run-on in the parser and I am not sure your proposal is the best solution. My feeling is that we need to test for EOF while reading the list: token lastToken(is); while ( !( lastToken.isPunctuation() && lastToken.pToken() == token::END_LIST ) ) { is.putBack(lastToken); if (is.eof()) { FatalIOErrorIn ( "PtrList<T>::read(Istream&, const INew&)", is ) << "Premature EOF after reading " << lastToken.info() << exit(FatalIOError); } sllPtrs.append(inewt(is).ptr()); is >> lastToken; } This works well for your test problem but needs to be tested on a wider range of parsing problems to be sure it is the optimal solution. |
|
All my tests have shown that the above solution resolves the problem. I have pushed the change into OpenFOAM-2.3.x and OpenFOAM-dev, could you test and confirm? |
|
This is a bit odd, because yesterday I had tested using "is.eof()" within the while statement and it didn't work... possibly I used it wrong. Either way, I'll test this on this coming weekend. It might be useful to keep this bug report open for others to give some feedback in the meantime as well. |
|
I've confirmed that this is working, at least for the tests I reported, along with a few more I tried in "topoSetDict". One way or another (error+abort or warnings), it no longer has the infinite loop it once had. |
|
Resolved by commit 88ac82c68913b458d7310dc8b59da6eccbb34154 |
Date Modified | Username | Field | Change |
---|---|---|---|
2015-02-17 17:25 | wyldckat | New Issue | |
2015-02-17 23:16 | henry | Note Added: 0003816 | |
2015-02-18 08:13 | henry | Note Added: 0003819 | |
2015-02-18 11:26 | wyldckat | Note Added: 0003828 | |
2015-02-21 12:58 | wyldckat | Note Added: 0003846 | |
2015-02-21 13:04 | henry | Note Added: 0003847 | |
2015-02-21 13:04 | henry | Status | new => resolved |
2015-02-21 13:04 | henry | Resolution | open => fixed |
2015-02-21 13:04 | henry | Assigned To | => henry |