Как использовать valgrind с python?
Я пытаюсь memcheck расширение Cython C, которое я пишу, но у меня возникли проблемы с настройкой 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) Применил патч кода, то есть "Uncomment Py_USING_MEMORY_DEBUGGER в объектах /obmalloc.c".
3) Применил патч подавления, то есть "Раскомментировать строки в Misc/valgrind-python.supp, которые подавляют предупреждения для PyObject_Free и PyObject_Realloc"
4) Скомпилированный питон с
./configure --prefix=/home/dejan/workspace/python --without-pymalloc
make -j4 install
Заметьте, что я сделал и 2, и 3, в то время как README.valgrind говорит, чтобы сделать 2 или 3... больше не может повредить.
Теперь давайте протестируем это на некотором образце кода python в test.py
print "Test"
Пусть запущен valgrind на python с помощью этого script
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 script, который не течет и не очистится от вывода valgrind?
Ответы
Ответ 1
Я нашел ответ здесь.
Python также необходимо скомпилировать в режиме отладки, то есть
./configure --prefix=/home/dejan/workspace/python --without-pymalloc --with-pydebug --with-valgrind
Кроме того, numpy имеет файл подтверждения , который избавляется от дополнительных предупреждений valgrind.
Ответ 2
Начиная с python 3.6 существует переменная окружения PYTHONMALLOC
, которая доступна в сборках релизов, без необходимости перекомпилировать.
PYTHONMALLOC=malloc python3 foobar.py
Это отключит pymalloc и просто будет использовать libc malloc напрямую, делая его valgrind-friendly. Это эквивалентно --without-pymalloc
(и это так же медленно)
Если valgrind слишком медленный, другие значения могут быть полезны. PYTHONMALLOC=debug
и PYTHONMALLOC=malloc_debug
добавьте отладочные крючки поверх дистрибутивов по умолчанию и libc соответственно. Их эффекты из документов:
- Недавно выделенная память заполняется байтом 0xCB
- Свободная память заполняется байтом 0xDB
- Обнаружение нарушений API-интерфейса распределителя памяти Python. Например, PyObject_Free() вызывается в блоке памяти, выделенном PyMem_Malloc().
- Обнаруживать записи до начала буфера (переполнение буфера)
- Обнаружение записи после окончания буфера (переполнение буфера)
- Убедитесь, что GIL удерживается, когда вызываются функции распределителя объектов PYMEM_DOMAIN_OBJ (например: PyObject_Malloc()) и PYMEM_DOMAIN_MEM (например: PyMem_Malloc()).
Это будет захватывать некоторые неинициализированные чтения, некоторые из них будут использоваться после бесплатного, некоторый буфер под/переполнение и т.д., но не сообщают об утечках и не коснутся памяти, которая не выделяется через python (при использовании glibc, MALLOC_PERTURB_
и MALLOC_CHECK_
переменные окружения могут помочь там)
См. также: