Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.4k
gh-120754: Ensure _stat_atopen is cleared on fd change#125166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Performed an audit of `fileio.c` and `_pyio` and made sure anytime thefd changes the stat result, if set, is also cleared/changed.There's one case where it's not cleared, if code would clear it in__init__, keep the memory allocated and just do another fstat with theexisting memory.
Modules/_io/fileio.c Outdated
| if (internal_close(self)<0) | ||
| /* Have to close the existing file first. | ||
| This leaves the stat so we can reuse the memory. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I don't think that this optimization is worth it, I would prefer to always clear the cache in close().
| #endif | ||
| } | ||
| PyMem_Free(self->stat_atopen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Not sure which is preferred here. The Free + New back to back feels weird, but version with the conditional feels like "extra work/code thatshould never be executed" (but that the compiler / tools that run currently won't validate...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Maybeif (ptr != NULL) free(ptr) would be more regular and avoid the 4 lines long comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Moved to that, dropped comment and simplified / back to always calling PyMem_New
vstinner left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
There are compiler warnings that you can see in the review tab.
cmaloney commentedOct 9, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I think the latest commit fixes the compiler warnings (was a testing/debugging assert I accidentally committed with a missing |
Uh oh!
There was an error while loading.Please reload this page.
cmaloney commentedOct 30, 2024
CI "Tests / Ubuntu SSL tests with OpenSSL" failed because of what looks like a network hang / not these changes: |
Modules/_io/fileio.c Outdated
| } | ||
| } | ||
| PyMem_Free(self->stat_atopen); | ||
| self->stat_atopen=NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
internal_close() already does the same, so it's redundant, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Tradeoff for matching what_pyio does which doesos.close() in these cases vs aninternal_close that does the OS close + other cleanup. Happy to drop though / definitely feels redundant to me in these two cases.
Modules/_io/fileio.c Outdated
| #endif | ||
| if (self->fd >=0) { | ||
| PyMem_Free(self->stat_atopen); | ||
| self->stat_atopen=NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
internal_close() already does the same, so it's redundant, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Moderately, in theself->closefd is false case behavior would differ from _pyio, but that will be caught by the PyMem_Free + PyMem_New below, so think this is always redundant / not needed
Modules/_io/fileio.c Outdated
| } | ||
| PyMem_Free(self->stat_atopen); | ||
| if (self->stat_atopen!=NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
PyMem_Free(NULL) is well defined: it does nothing, so you might omit theif (stat_atopen != NULL) test.
72dd471 intopython:mainUh oh!
There was an error while loading.Please reload this page.
vstinner commentedNov 1, 2024
Merged, thank you. |
…n#125166)Performed an audit of `fileio.c` and `_pyio` and made sure anytime thefd changes the stat result, if set, is also cleared/changed.There's one case where it's not cleared, if code would clear it in__init__, keep the memory allocated and just do another fstat with theexisting memory.
…n#125166)Performed an audit of `fileio.c` and `_pyio` and made sure anytime thefd changes the stat result, if set, is also cleared/changed.There's one case where it's not cleared, if code would clear it in__init__, keep the memory allocated and just do another fstat with theexisting memory.
Uh oh!
There was an error while loading.Please reload this page.
While adding _stat_atopen I accidentally created a leak in the C implementation because the
_stat_atopenmember was set to NULL in the C implementation, but the memory wasn't freed. That was resolved, but it showed there were a number of potential cases where_stat_atopenshould be cleared (the information is out of date because the fd changed) that it was not. In this PR I audited by reading through FileIO (in _io and _pyio), and in all cases where the fd is changed/closed made sure to clear/reset _stat_atopen as well.Followup from:#124225 (comment), cc:@vstinner