J'essaie de vérifier une extension C python que j'écris, mais j'ai du mal à configurer valgrind pour fonctionner avec python. J'apprécierais vraiment quelques conseils. Juste pour le contexte, c'est Ubuntu 13.10, python 2.7.5+, et valgrind 3.8.1.
Selon la recommandation de Readme.valgrind
J'ai fait ce qui suit.
1) Téléchargé la source python avec
Sudo apt-get build-dep python2.7
apt-get source python2.7
2) Appliqué le correctif de code, c'est-à-dire "Décommenter Py_USING_MEMORY_DEBUGGER dans Objects/obmalloc.c".
3) Appliqué le correctif de suppression, c'est-à-dire "Décommentez les lignes dans Misc/valgrind-python.supp qui suppriment les avertissements pour PyObject_Free et PyObject_Realloc"
4) Compilé python avec
./configure --prefix=/home/dejan/workspace/python --without-pymalloc
make -j4 install
Notez que j'ai fait à la fois 2 et 3, tandis que README.valgrind dit de faire 2 ou 3 ... plus ne peut pas faire de mal.
Maintenant, testons cela sur un exemple de code python dans test.py
print "Test"
Lançons valgrind sur python avec ce script
valgrind --tool=memcheck --leak-check=full --suppressions=python2.7-2.7.5/Misc/valgrind-python.supp bin/python test.py
De manière inattendue, il y a encore beaucoup de rapports de valgrind, le premier étant (et beaucoup d'autres après)
==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)
Est-ce que je fais quelque chose de mal? Existe-t-il un moyen de valgrind un script python qui ne fuit pas et n'obtienne pas une sortie valgrind propre?
J'ai trouvé la réponse ici .
Python doit également être compilé en mode débogage, c'est-à-dire.
./configure --prefix=/home/dejan/workspace/python --without-pymalloc --with-pydebug --with-valgrind
De plus, numpy a un fichier de suppression qui supprime les avertissements supplémentaires de valgrind.
Depuis python 3.6, il existe une variable d'environnement PYTHONMALLOC
qui est disponible dans les versions, sans avoir besoin de recompiler.
PYTHONMALLOC=malloc python3 foobar.py
Cela désactivera pymalloc et utilisera simplement libc malloc directement, le rendant compatible avec valgrind. Cela équivaut à --without-pymalloc
(et c'est tout aussi lent)
Si valgrind est trop lent, d'autres valeurs peuvent être utiles. PYTHONMALLOC=debug
et PYTHONMALLOC=malloc_debug
ajouter des crochets de débogage au-dessus des allocateurs par défaut et libc respectivement. Leurs effets, à partir des documents:
- La mémoire nouvellement allouée est remplie par l'octet 0xCB
- La mémoire libérée est remplie par l'octet 0xDB
- Détectez les violations de l'API d'allocation de mémoire Python. Par exemple, PyObject_Free () a appelé un bloc de mémoire alloué par PyMem_Malloc ().
- Détecter les écritures avant le début d'un buffer (buffer underflows)
- Détecter les écritures après la fin d'un tampon (débordements de tampon)
- Vérifiez que le GIL est conservé lors de l'appel des fonctions d'allocateur des domaines PYMEM_DOMAIN_OBJ (ex: PyObject_Malloc ()) et PYMEM_DOMAIN_MEM (ex: PyMem_Malloc ()).
Cela interceptera certaines lectures non initialisées, certaines utilisations après la libération, certains tampons sous/débordements, etc., mais ne signalera pas de fuites et ne touchera pas la mémoire qui n'est pas allouée via python (Quand en utilisant la glibc, le MALLOC_PERTURB_
et MALLOC_CHECK_
les variables d'environnement pourraient y aider)
Voir également: