How to use valgrind with python?
Since python 3.6, there's a PYTHONMALLOC
environment variable which is available in release builds, without needing to recompile.
PYTHONMALLOC=malloc python3 foobar.py
This will disable pymalloc and just use the libc malloc directly, making it valgrind-friendly. This is equivalent to --without-pymalloc
(and it is just as slow)
If valgrind is too slow, other values can be helpful. PYTHONMALLOC=debug
and PYTHONMALLOC=malloc_debug
add debug hooks on top of the default and the libc allocators respectively. Their effects, from the docs:
- 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.
This will catch some uninitialized reads, some use after free, some buffer under/overflows, etc, but won't report leaks and won't touch memory that isn't allocated through python (When using glibc, the MALLOC_PERTURB_
and MALLOC_CHECK_
environment variables might help there)
See also:
- Details of the available values
- 3.6 release notes with usage notes
- Current location of README.valgrind
I found the answer here.
Python also needs to be compiled in debug mode, i.e.
./configure --prefix=/home/dejan/workspace/python --without-pymalloc --with-pydebug --with-valgrind
In addition, numpy has a suppresion file that gets rid of the extra valgrind warnings.