This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author dralley
Recipients dralley
Date 2020-10-31.16:16:39
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1604161000.37.0.700108867907.issue42221@roundup.psfhosted.org>
In-reply-to
Content
Disclaimer: I'm not familiar with the interpreter internals, nor am I really a C dev, so I could be misinterpreting these results due to inexperience.

I've been attempting to debug a memory leak which I thought was caused by a C API extension that we are using.  When running the unit tests for this library under valgrind, I get a couple of results like the following, where the bottom of the call stack is a realloc() triggered by _PyUnicodeWriter_Finish()

==5732== 76 bytes in 1 blocks are definitely lost in loss record 4,571 of 9,822
==5732==    at 0x4C2C291: realloc (vg_replace_malloc.c:836)
==5732==    by 0x4F52323: _PyUnicodeWriter_Finish (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4F5A087: PyUnicode_FromFormatV (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4F937BC: PyErr_FormatV (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4F93433: PyErr_Format (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4F836B9: _PyEval_EvalFrameDefault (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4F87C9E: PyEval_EvalCodeEx (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4EF6DE2: ??? (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0x4EDEF62: PyObject_Call (in /usr/lib64/libpython3.6m.so.1.0)
==5732==    by 0xF9785EF: c_warningcb (in /usr/local/lib/pulp/lib/python3.6/site-packages/createrepo_c/_createrepo_c.so)
==5732==    by 0xF98F897: cr_xml_parser_warning (in /usr/local/lib/pulp/lib/python3.6/site-packages/createrepo_c/_createrepo_c.so)
==5732==    by 0xF98B59E: cr_start_handler (in /usr/local/lib/pulp/lib/python3.6/site-packages/createrepo_c/_createrepo_c.so)

There is no explicit call to realloc() in that function, but there is a call to resize_compact(), which in turn calls PyObject_Realloc(). I assume all those are getting inlined which is why it looks like there's nothing in-beteween -- if not, then maybe the leak is actually somewhere else.

The following is speculation given that I have limited understanding of interpreter workings.

In the version of Python I am using (3.6), resize_compact() has some code that looks suspicious to me: [0]

Two things jump out: 

1) "_Py_ForgetReference(unicode)", which according to this mailing list email [1] is used "to avoid having the deallocator run as result of the
DECREF".  The definition and usage of "_Py_ForgetReference(unicode)" in newer versions of Python is hidden behind "#ifdef Py_TRACE_REFS" flags [2], but it was not being done previously, which raises the question if perhaps it was being used improperly in previous versions. Forgetting about an object without deallocating it would certainly cause a leak.

2) When comparing [0] to a nearly identical piece of code meant for resizing bytestrings [3], I notice that in the branch handling the out of memory case, the bytestring version calls "PyObject_Del()" whereas the unicode version calls "_Py_NewReference()".

Can someone with more knowledge take a look at this?  And if neither of these are "the problem" then perhaps help me investigate what might be causing this Valgrind output?


[0] https://github.com/python/cpython/blob/3.6/Objects/unicodeobject.c#L943-L952

[1] https://www.mail-archive.com/python-dev@python.org/msg108525.html

[2] https://github.com/python/cpython/pull/18332/files#diff-34c966e7876d6f8bf801dd51896327e4f68bba02cddb95fbf3963f0b2e39c38aR1043-R1045

[3] https://github.com/python/cpython/blob/3.6/Objects/bytesobject.c#L3006-L3015
History
Date User Action Args
2020-10-31 16:16:40dralleysetrecipients: + dralley
2020-10-31 16:16:40dralleysetmessageid: <1604161000.37.0.700108867907.issue42221@roundup.psfhosted.org>
2020-10-31 16:16:40dralleylinkissue42221 messages
2020-10-31 16:16:39dralleycreate