我尝试在Python C扩展中调试内存崩溃,并尝试在valgrind下运行脚本。我发现valgrind输出中有太多的“噪音”,即使我运行简单的命令:
valgrind python -c ""
Valgrind输出完整的重复信息,如下所示:
==12317== Invalid read of size 4
==12317== at 0x409CF59: PyObject_Free (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x405C7C7: PyGrammar_RemoveAccelerators (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x410A1EC: Py_Finalize (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x4114FD1: Py_Main (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x8048591: main (in /usr/bin/python2.5)
==12317== Address 0x43CD010 is 7,016 bytes inside a block of size 8,208 free'd
==12317== at 0x4022F6C: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==12317== by 0x4107ACC: PyArena_Free (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x41095D7: PyRun_StringFlags (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40DF262: (within /usr/lib/libpython2.5.so.1.0)
==12317== by 0x4099569: PyCFunction_Call (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40E76CC: PyEval_EvalFrameEx (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40E70F3: PyEval_EvalFrameEx (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40E896A: PyEval_EvalCodeEx (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40E8AC2: PyEval_EvalCode (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40FD99C: PyImport_ExecCodeModuleEx (in /usr/lib/libpython2.5.so.1.0)
==12317== by 0x40FFC93: (within /usr/lib/libpython2.5.so.1.0)
==12317== by 0x41002B0: (within /usr/lib/libpython2.5.so.1.0)
Slackware 12.2上的Python 2.5.2。
这是正常行为吗?如果是这样,那么valgrind可能是用于调试Python内存错误的不适当的工具吗?
答案 0 :(得分:22)
您可以尝试使用python源附带的suppression file
阅读Python Valgrind README也是一个好主意!
答案 1 :(得分:2)
这在任何大型系统中都很常见。您可以使用Valgrind的suppression system明确禁止您不感兴趣的警告。
答案 2 :(得分:1)
最正确的选择是告诉Valgrind它应该拦截Python的分配函数。 您应该修补valgrind / coregrind / m_replacemalloc / vg_replace_malloc.c,为PyObject_Malloc,PyObject_Free,PyObject_Realloc添加新的拦截器,例如:
ALLOC_or_NULL(NONE, PyObject_Malloc, malloc);
(请注意,用户分配函数的soname应为NONE
)
答案 3 :(得分:1)
通过Nick I给出的链接,我可以在README.valgrind上找到一些更新。一句话,对于Python> 3.6,您可以设置PYTHONMALLOC=malloc
环境变量来有效地禁用警告。例如,在我的机器上:
export PYTHONMALLOC=malloc
valgrind python my_script.py
不会产生与python相关的任何错误。
答案 4 :(得分:0)
是的,这是典型的。大型系统通常会使内存无法释放,只要它是一个恒定的数量,这是很好的,并且与系统的运行历史不成比例。 Python解释器属于这一类。
也许您可以过滤valgrind输出以仅关注在C扩展中进行的分配?
答案 5 :(得分:0)
我找到了另一种选择。 James Henstridge有python的自定义构建,它可以检测到在valgrind下运行的python以及在这种情况下pymalloc allocator被禁用的事实,PyObject_Malloc / PyObject_Free传递到正常的malloc / free,valgrind知道如何跟踪。