python - 如何在 python 中使用 valgrind?

标签 python memory-leaks valgrind

我正在尝试 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

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

请注意,我同时执行了 2 和 3,而 README.valgrind 说要执行 2 或 3... 更多也无妨。

现在,让我们在 test.py

中的一些示例 python 代码上进行测试
print "Test"

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

valgrind --tool=memcheck --leak-check=full --suppressions=python2.7-2.7.5/Misc/valgrind-python.supp bin/python test.py

出乎意料的是,仍然有大量来自 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)

我做错了吗?有没有办法对不泄漏的python脚本进行valgrind并获得干净的valgrind输出?

最佳答案

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

PYTHONMALLOC=malloc python3 foobar.py

这将禁用 pymalloc 并直接使用 libc malloc,使其对 valgrind 友好。这等价于 --without-pymalloc (同样慢)

如果 valgrind 太慢,其他值可能会有所帮助。 PYTHONMALLOC=debugPYTHONMALLOC=malloc_debug 分别在默认分配器和 libc 分配器之上添加调试钩子(Hook)。它们的效果,来自文档:

  • Newly allocated memory is filled with the byte 0xCB
  • Freed memory is filled with the byte 0xDB
  • Detect violations of the Python memory allocator API. For example, PyObject_Free() called on a memory block allocated by PyMem_Malloc().
  • Detect writes before the start of a buffer (buffer underflows)
  • Detect writes after the end of a buffer (buffer overflows)
  • Check that the GIL is held when allocator functions of PYMEM_DOMAIN_OBJ (ex: PyObject_Malloc()) and PYMEM_DOMAIN_MEM (ex: PyMem_Malloc()) domains are called.

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

另见:

关于python - 如何在 python 中使用 valgrind?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20112989/

相关文章:

python - 在 ModelMultipleChoiceField 中定义选项时如何组合两个查询集?

python - 对 `is` 运算符与字符串感到困惑

python - 有没有办法从 ElementTree 元素中获取行号

c++ - 创建本地 opencv mat 对象时内存泄漏

java - 调试内存泄漏 - org.hibernate.engine.StatefulPersistenceContext

c - 内存泄漏和无效读/写

c - 带有 icd 指针的 C 代码中的 Valgrind 错误

android - 无法使用 Valgrind 运行 Java Android 程序

python - 是否有 Python 等同于 Java 的 Groovy/Grails

shell - 从 valgrind 输出中过滤掉垃圾