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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python leaks one reference at exit on Windows #91013
Comments
"./python -X showrefcount -I -c pass" returns "[0 refs, 0 blocks]" as expected on Linux: Python doesn't leak any reference nor memory block. But on Windows, it still leaks 1 reference (and 1 memory block)! vstinner@DESKTOP-DK7VBIL C:\vstinner\python\main>python -X showrefcount -I -c pass I recently added a test in test_embed which now fails on Windows. See bpo-1635741 "Py_Finalize() doesn't clear all Python objects at exit" for the context. |
Good news, the difference on Windows was easy enough to find, bad news total refs are now negative! --- a/Objects/exceptions.c #define INIT_ALIAS(NAME, TYPE) \
do { \
- Py_INCREF(PyExc_ ## TYPE); \
- Py_XDECREF(PyExc_ ## NAME); \
+ Py_XSETREF(PyExc_ ## NAME, PyExc_ ## TYPE); \
PyExc_ ## NAME = PyExc_ ## TYPE; \
if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## NAME)) { \
return -1; \ As the PyExc_* aliases just deprecated names for PyExc_OSError, there is no need to increment their refcounts. Or they could be decremented in Fini(). Or they could finally be removed entirely. |
Note that an allocated block is still leaking. Strange as well, when using dump_refs, the total refs are much more negative (-12 linux, -13 Windows) |
Oh wow. How did you find this leak? Did you read all C files and check for code specific to Windows? How did you proceed? Well spotted!
I proposed #75775 to fix this macro.
Which command do you type? Do you pass -I option to Python? With my PR, I get exactly 0 on Linux: $ ./python -I -X showrefcount -c pass
[0 refs, 0 blocks]
Right, with my PR, I now get 1 leaked memory block on Windows:
|
Initially, I modified Py_INCREF to dump the object (addr & tp_name) on
For both as -I disables environment lookup:
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -757,6 +757,7 @@ config_init_defaults(PyConfig *config)
config->user_site_directory = 1;
config->buffered_stdio = 1;
config->pathconfig_warnings = 1;
+ config->dump_refs = 1;
#ifdef MS_WINDOWS
config->legacy_windows_stdio = 0;
#endif For linux: For Windows:
Even using that change, I still have negative refs (but I still have |
(that's what I get for typing from memory):
I initially missed the _PySet_Dummy change, with that total refs (w/o |
That's smart! Thanks for sharing. It may help to identify future leaks.
Ah, maybe testing with Py_TRACE_REFS shows more bugs. I didn't try Py_TRACE_REFS recently. Well, if someone finds why it's becoming negative, a fix would be welcomed :-) |
I just built Python with --with-trace-refs. On Linux, it works as expected: $ ./python -I -X showrefcount -c pass
[0 refs, 0 blocks] |
Did you also modify initconfig.c? That part is required as the usual |
Ah, with PYTHONDUMPREFS=1 (and without -I), I get a negative ref count: $ PYTHONDUMPREFS=1 ./python -X showrefcount -c pass
[-10 refs, 0 blocks] I don't plan to investigate this issue. I'm not using PYTHONDUMPREFS=1 anymore. |
The initial issue "Python leaks one reference at exit on Windows" is now fixed. If someone wants to investigate the remaining leak of 1 memory block or the negative ref count of PYTHONDUMPREFS=1, please open a separated issue. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: