Отладка памяти Python с помощью GDB

У нас есть приложение для Linux, которое использует привязки OpenSSL для Python, и я подозреваю, что оно вызывает случайные сбои. Иногда мы видим, что он вылетает с сообщением:

Python Fatal Error: GC Object already tracked

что могло бы показаться либо ошибкой программирования со стороны библиотеки, либо признаком повреждения памяти. Есть ли способ узнать последнюю выполненную строку исходного кода Python, учитывая файл ядра? Или если он прикреплен в GDB? Я понимаю, что это, вероятно, весь скомпилированный байт-код, но я надеюсь, что кто-то мог с этим справиться. В настоящее время он работает с активным модулем трассировки, и мы надеемся, что это повторится снова, но это может занять много времени.

Вы используете эту программу в 64-битном Linux?

Douglas Mayle 07.11.2008 21:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
1
4 228
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Если у вас есть Mac или Sun Box, вы можете использовать dtrace и версию python, скомпилированную с dtrace, чтобы выяснить, что приложение делало в то время. Примечание: в 10.5 python предварительно скомпилирован с помощью dtrace, что действительно приятно и удобно.

Если это недоступно для вас, вы можете импорт gc и включить отладку, которую затем можно записать в файл журнала.

Чтобы конкретно ответить на ваш вопрос об отладке с помощью GDB, вы можете прочитать «Отладка с помощью GDB» в вики-странице python.

Ответ принят как подходящий

Да, вы можете делать такие вещи:

(gdb) print PyRun_SimpleString("import traceback; traceback.print_stack()")
  File "<string>", line 1, in <module>
  File "/var/tmp/foo.py", line 2, in <module>
    i**2
  File "<string>", line 1, in <module>
$1 = 0

Также должно быть возможно использовать команду pystack, определенную в файле python gdbinit, но у меня она не работает. Это обсуждается здесь, если вы хотите в него разобраться.

Кроме того, если вы подозреваете проблемы с памятью, стоит отметить, что вы можете использовать valgrind с python, если вы готовы его перекомпилировать. Процедура описана здесь.

Если я помню, файл gdbinit нужно изменить, потому что порядок функций в файлах .c изменился. Так было в последний раз, когда я использовал gdb + python. Я должен был отправить патч ...

Tony Arkles 07.11.2008 22:01

Отлично, оставлю его запущенным под GDB и надеюсь, что он выйдет из строя на выходных.

Matt Green 07.11.2008 22:07

Раньше не замечал, но дампы керна были в разных местах. Это почти наверняка повреждение памяти. Огромное спасибо!

Matt Green 07.11.2008 22:40

Нет проблем, Мэтт. Тони, команда pystack не работает, потому что она ссылается на переменную «co», которой нет в текущем кадре.

Alex Coventry 08.11.2008 19:03

Если вы используете CDLL для обертывания библиотеки C в python, а это 64-битный Linux, есть большая вероятность, что ваша оболочка CDLL настроена неправильно. По умолчанию CDLL использует возвращаемые типы int на всех платформах (в 64-битных системах должно быть long long) и просто ожидает, что вы передадите правильные аргументы. В этом случае вам может потребоваться проверить оболочку CDLL ...

В дополнение ко всему вышесказанному можно быстро реализовать специальный трассировщик через модуль трассировки.

Другие вопросы по теме