18

我尝试在我的 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 中调试内存错误?

4

6 回答 6

22

您可以尝试使用python 源附带的抑制文件

阅读Python Valgrind README也是一个好主意!

于 2009-10-05T11:45:32.207 回答
3

按照 Nick 提供的链接,我可以在README.valgrind上找到一些更新。总之,对于 Python > 3.6,您可以设置PYTHONMALLOC=malloc环境变量以有效禁用警告。例如,在我的机器上:

export PYTHONMALLOC=malloc
valgrind python my_script.py

不会产生任何与 python 相关的错误。

于 2018-11-17T09:18:14.220 回答
2

这在任何大型系统中都很常见。您可以使用 Valgrind 的抑制系统来显式抑制您不感兴趣的警告。

于 2009-10-05T11:29:16.783 回答
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

于 2009-12-18T09:22:51.340 回答
0

是的,这很典型。大型系统通常不会释放内存,这很好,只要它是一个常数,并且与系统的运行历史不成比例。Python 解释器属于这一类。

也许您可以过滤 valgrind 输出以仅关注 C 扩展中所做的分配?

于 2009-10-05T11:23:35.140 回答
0

我发现了另一种选择。James Henstridge 有自定义的 python 构建,它可以检测到 python 在 valgrind 下运行的事实,在这种情况下 pymalloc 分配器被禁用,PyObject_Malloc/PyObject_Free 传递到正常的 malloc/free,valgrind 知道如何跟踪。

此处提供软件包:https ://launchpad.net/~jamesh/+archive/python

于 2009-12-02T12:20:27.270 回答