bpo-34080: Fix memory leak on parsing error#8242
Conversation
|
"./python -m test -j0 -R 3:3 test_compile test_grammar" pass with this change. |
Sorry, something went wrong.
|
I have wrote the same fix, but not published it because failed with writing a test for bpo-34084. Could you please write a test? Shouldn't you remove PyObject_FREE from err_input? |
Sorry, something went wrong.
|
The commit message is misleading. The leak was caused by the bug in |
Sorry, something went wrong.
* bpo-34080, bpo-34084: err_free() now always releases 'text' memory allocated by PyObject_Malloc() to fix a memory leak on parsing error. Previously, err->text was not released (by err_input()) on E_ERROR error. * Remove also "with Barry as BDFL, use '<>' instead of '!='" static string error message (previously set to err_ret->text) because in practice, err_ret->text is always set later. Add also an assertion to make sure that err_ret->text is only set once. * Replace old PyObject_MALLOC() and PyObject_FREE() aliases with PyObject_Malloc() and PyObject_Free() function calls. Co-Authored-By: Serhiy Storchaka <storchaka@gmail.com> Co-Authored-By: Xiang Zhang <angwerzx@126.com>
In fact, bpo-34084 is not a bug, just dead code: I changed my PR to remove dead code, but I also added an assertion to make sure that the 'text' field is only set once.
It's harmless. I prefer to release memory as soon as possible.
I used "git push --force" to rewrite the commit message. Oops, I also fix my commit message: err_clear() => err_free(). |
Sorry, something went wrong.
|
Ahh, I don't read the entire code path carefully. It's just dead code. But I don't quite understand why put the cleaning logic two places. I know it's harmless, but it looks to me only the |
Sorry, something went wrong.
Then it should be in err_input for E_ERROR too, isn't? |
Sorry, something went wrong.
|
Ok ok, I removed the code clearing the 'text' field from err_input() and marked its argument as constant to make it more explicit that err_input() intent is only to raise an exception, whereas err_free() is used to free memory. |
Sorry, something went wrong.
Thanks. But I would like to see @serhiy-storchaka opinion on the latest version of my PR :-) |
Sorry, something went wrong.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
I'm not convinced there is a need in such complication. Note that this PR changes public (although undocumented) C API: PyParser_SetError(). And it would be less easier to backport it to 2.7 than #8222.
Sorry, something went wrong.
Sorry, I fail to see how my change makes the code more complicated. Would you mind to elaborate?
Sorry, what do you mean by "changing" the function? My PR doesn't change the behaviour of the function, it still raises a Python exception from a 'perrdetail' structure. The only changes is that with my change, it no longer releases the memory. Does it really matter when the memory is released? There is PyParser_ClearError() which free the memory. Hum, sadly PyParser_ClearError is not documented neither. It seems like only high-level functions are exposed (documented), so this PR should not be noticed by anyone.
This PR also fixes https://bugs.python.org/issue34084 Honestly, I don't understand why you are working so hard against this change: it's short, straighforward, and it fixes a real bug. Moreover, I already fixed multiple issues that you reported on previous versions of my change... |
Sorry, something went wrong.
In comparison with a one-line change in #8222 which also fixes a real bug, it is much more complex.
This change is not necessary for fixing a real bug. As such, it should be discussed separately and made only in master.
Is there a reproducer for this bug? It looks to me that it can't be reproduced due to other bug. I think it would be better to fix the broken easter egg than remove the part of the broken code. There is no haste here, in contrary to fixing the memory leak. |
Sorry, something went wrong.
|
I wrote a simpler PR to fix https://bugs.python.org/issue34084: PR #8259. |
Sorry, something went wrong.
allocated by PyObject_Malloc() to fix a memory leak on parsing
error. Previously, err->text was not released (by err_input()) on
E_ERROR error.
string error message (previously set to err_ret->text) because in
practice, err_ret->text is always set later. Add also an assertion
to make sure that err_ret->text is only set once.
PyObject_Malloc() and PyObject_Free() function calls.
Co-Authored-By: Serhiy Storchaka storchaka@gmail.com
Co-Authored-By: Xiang Zhang angwerzx@126.com
https://bugs.python.org/issue34080