Cómo usar valgrind con python?


Estoy intentando comprobar una extensión de python en C que estoy escribiendo, pero tengo problemas para configurar valgrind para trabajar con python. Realmente apreciaría un consejo. Solo para el contexto, esto es Ubuntu 13.10, python 2.7.5+, y valgrind 3.8.1.

Según la recomendación de Readme.valgrind hice lo siguiente.

1) Descargado el código fuente de python con

sudo apt-get build-dep python2.7
apt-get source python2.7

2) Se aplicó el parche de código, es decir, "Uncomment Py_USING_MEMORY_DEBUGGER in Objects/obmalloc.c".

3) Se ha aplicado el parche de supresión, es decir, "Descomentar las líneas en Misc / valgrind-python.supp que suprime las advertencias para PyObject_Free y PyObject_Realloc "

4) Python compilado con

./configure --prefix=/home/dejan/workspace/python --without-pymalloc
make -j4 install

Tenga en cuenta que hice ambos 2 y 3, mientras README.valgrind dice que hagamos 2 o 3... más no puede hacer daño.

Ahora, probemos esto en un código python de ejemplo en test.py

print "Test"

Vamos a ejecutar valgrind en python con este script

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

Inesperadamente, todavía hay un montón de informes de valgrind, siendo el primero (y muchos más siguientes)

==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)

Estoy haciendo algo mal? ¿Hay una manera de valgrind un script python que no se filtre y obtenga una salida valgrind limpia?

Author: Dejan Jovanović, 2013-11-21

2 answers

Encontré la respuesta aquí.

Python también necesita ser compilado en modo de depuración, es decir,

./configure --prefix=/home/dejan/workspace/python --without-pymalloc --with-pydebug --with-valgrind

Además, numpy tiene un archivo de suppresion que elimina las advertencias adicionales de valgrind.

 38
Author: Dejan Jovanović,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-20 01:35:06

Desde python 3.6, hay una variable de entorno PYTHONMALLOC que está disponible en las compilaciones de versiones, sin necesidad de recompilar.

PYTHONMALLOC=malloc python3 foobar.py

Esto deshabilitará pymalloc y simplemente usará el libc malloc directamente, haciéndolo amigable con valgrind. Esto es equivalente a --without-pymalloc (y es igual de lento)

Si valgrind es demasiado lento, otros valores pueden ser útiles. PYTHONMALLOC=debug y PYTHONMALLOC=malloc_debug añaden hooks de depuración sobre los asignadores predeterminados y libc respectivamente. Sus efectos, de los documentos:

  • La memoria recién asignada se llena con el byte 0xCB
  • La memoria liberada se llena con el byte 0xDB
  • Detectar violaciones de la API de asignación de memoria de Python. Por ejemplo, PyObject_Free () llama a un bloque de memoria asignado por PyMem_Malloc ().
  • Detecta las escrituras antes del inicio de un buffer (buffer underflows)
  • Detecta las escrituras después del final de un buffer (buffer overflows)
  • Compruebe que el GIL se mantiene cuando las funciones de asignación de Los dominios PYMEM_DOMAIN_OBJ (ej: PyObject_Malloc()) y PYMEM_DOMAIN_MEM (ej: PyMem_Malloc()) son llamados.

Esto capturará algunas lecturas no inicializadas, algunos usos después de free, algunos búfer debajo / overflows, etc, pero no reportará fugas y no tocará la memoria que no está asignada a través de python (Cuando se usa glibc, las variables de entorno MALLOC_PERTURB_ y MALLOC_CHECK_ podrían ayudar)

Véase también:

 12
Author: dequis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 23:17:01