Как найти утечки в библиотеках ctypes Python

Я работаю над приложением Python, которое использует несколько сторонних библиотек с открытым исходным кодом. Одна из библиотек основана на ctypes, и я недавно обнаружил в ней более 10 отдельных утечек памяти. Причины этих утечек варьировались от круговых ссылок на объекты с явными деструкторами (которые Python не может собирать мусор) с использованием c_char_p в качестве возврата type для функций, возвращающих неконстантные массивы символов (в результате массивы символов преобразуются автоматически в строки Python, а исходные массивы, выделенные C, никогда не освобождаются.)

Я исправил обнаруженные утечки и отправил запрос на перенос автору библиотеки. Я сделал очень неформальное тестирование, создавая и удаляя объекты в цикле и наблюдая за использованием памяти Python, как и я, и я думаю, что нашел все утечки. Однако, поскольку я планирую использовать эту библиотеку в приложении, которое я бы хотел открыть, и, надеюсь, есть несколько других людей, я бы хотел быть более уверенным в этом. Поэтому мой вопрос: существует систематический способ найти утечки памяти в библиотеках на основе ctypes?

В процессе исправления утечек, которые я уже нашел, я попробовал Heapy и objgraph, но они не были особенно полезны для этой цели. Насколько я могу судить, обе они будут отображать только объекты, выделенные в куче Python, поэтому они не нужны для обнаружения утечек, вызванных неправильной обработкой пространства кучи, выделенного библиотеками C. Есть ли инструмент, который я могу использовать в Python, который может показать мне выделение на куче C, и желательно также, какие объекты Python, если таковые имеются, относятся к выделенным адресам?

Ответ 1

Вы можете попробовать запустить приложение под Valgrind. Valgrind - полезный инструмент для использования памяти профилей в скомпилированных приложениях. Это, по крайней мере, обнаружит ссылки и сообщит об их источнике.

Вы обязательно получите ложные срабатывания от вызовов Python. Ознакомьтесь с этим сайтом для приятного описания того, как использовать подавления, которые позволяют вам специально игнорировать определенные типы ошибок. См. Также Python готовит список запретов (здесь), и описание причины они необходимы (здесь).