如何使用valgrind与python?

Dej*_*vić 45 python valgrind memory-leaks

我正在尝试memcheck我写的C python扩展,但是我在设置valgrind以使用python时遇到了麻烦.我真的很感激一些建议.仅供上下文使用,这是Ubuntu 13.10,python 2.7.5+和valgrind 3.8.1.

根据Readme.valgrind我的建议,我做了以下.

1)用.下载python源码

sudo apt-get build-dep python2.7
apt-get source python2.7
Run Code Online (Sandbox Code Playgroud)

2)应用代码补丁,即"在Objects/obmalloc.c中取消注释Py_USING_MEMORY_DEBUGGER".

3)应用抑制补丁,即"取消注释Misc/valgrind-python.supp中的行,以抑制PyObject_Free和PyObject_Realloc的警告"

4)编译python与

./configure --prefix=/home/dejan/workspace/python --without-pymalloc
make -j4 install
Run Code Online (Sandbox Code Playgroud)

请注意,我做了2和3,而README.valgrind说做2或3 ...更多不能伤害.

现在,让我们在一些示例python代码中对此进行测试 test.py

print "Test"
Run Code Online (Sandbox Code Playgroud)

让我们用这个脚本在python上运行valgrind

valgrind --tool=memcheck --leak-check=full --suppressions=python2.7-2.7.5/Misc/valgrind-python.supp bin/python test.py
Run Code Online (Sandbox Code Playgroud)

出乎意料的是,仍然有来自valgrind的大量报告,其中第一个报告(以及更多关注报告)

==27944== HEAP SUMMARY:
==27944==     in use at exit: 857,932 bytes in 5,144 blocks  
==27944==   total heap usage: 22,766 allocs, 17,622 frees, 4,276,934 bytes allocated
==27944== 
==27944== 38 bytes in 1 blocks are possibly lost in loss record 24 of 1,343
==27944==    at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27944==    by 0x46B8DD: PyString_FromString (stringobject.c:143)
==27944==    by 0x439631: PyFile_FromFile (fileobject.c:157)
==27944==    by 0x4E9B4A: _PySys_Init (sysmodule.c:1383)
==27944==    by 0x4E29E9: Py_InitializeEx (pythonrun.c:222)
==27944==    by 0x4154B4: Py_Main (main.c:546)
==27944==    by 0x577DDE4: (below main) (libc-start.c:260)
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?有没有办法valgrind一个不泄漏的python脚本并获得干净的valgrind输出?

Dej*_*vić 44

我在这里找到了答案.

Python也需要在调试模式下编译,即

./configure --prefix=/home/dejan/workspace/python --without-pymalloc --with-pydebug --with-valgrind
Run Code Online (Sandbox Code Playgroud)

另外,numpy有一个suppresion文件可以摆脱额外的valgrind警告.


deq*_*uis 18

从python 3.6开始,有一个PYTHONMALLOC环境变量可以在发布版本中使用,而无需重新编译.

PYTHONMALLOC=malloc python3 foobar.py
Run Code Online (Sandbox Code Playgroud)

这将禁用pymalloc并直接使用libc malloc,使其对valgrind友好.这相当于--without-pymalloc(而且速度一样慢)

如果valgrind太慢,其他值可能会有所帮助.PYTHONMALLOC=debugPYTHONMALLOC=malloc_debug分别在默认值和libc分配器之上添加调试挂钩.他们的影响,来自文档:

  • 新分配的内存用字节0xCB填充
  • 释放的内存充满字节0xDB
  • 检测违反Python内存分配器API的情况.例如,PyObject_Free()调用由PyMem_Malloc()分配的内存块.
  • 在缓冲区启动之前检测写入(缓冲区下溢)
  • 在缓冲区结束后检测写入(缓冲区溢出)
  • 当调用PYMEM_DOMAIN_OBJ(例如:PyObject_Malloc())和PYMEM_DOMAIN_MEM(例如:PyMem_Malloc())域的分配器函数时,检查是否保持GIL.

这将捕获一些未初始化的读取,一些在空闲后使用,一些缓冲区在/溢出等,但不报告泄漏并且不会触及未通过python分配的内存(当使用glibc时,MALLOC_PERTURB_MALLOC_CHECK_环境变量可能有帮助那里)

也可以看看: