Получить stacktrace из застрявшего процесса python

Мне надо бежать в наследство сайт Zope2 и проблемы с ним. Самая большая проблема заключается в том, что иногда он просто блокируется, работает при 100% загрузке процессора и больше не отвечает на запросы. Хотя проблема не воспроизводима на регулярной основе, одна страница, содержащая 3 динамических графика, иногда запускает ее, поэтому я подозреваю какое-то состояние гонки, которое приводит к бесконечному циклу или застрявшему busywait.

проблема в том, что я еще не нашел способ отладить эту вещь. Нет ничего в журналах Zope и ничего в системных журналах. Я пробовал предложения от этот вопрос чтобы получить stacktrace, но единственный сигнал, который имеет какой-либо эффект SIGKILL.

есть ли другая возможность узнать, где именно находится процесс, когда он застревает?

5 ответов


Если процесс застрял таким образом, что никакой другой сигнал не проходит, вы можете рассмотреть возможность запуска его из отладчика, а не пытаться подключиться к нему во время выполнения.

кроме того, это может быть полезно для других тактик отладки, таких как отключение определенных частей кода, чтобы узнать минимальный случай, в котором он все еще воспроизводим, чтобы увидеть, что вызывает его лучше.


вы можете распечатать хорошую трассировку стека с помощью pyrasite.

во-первых, вам нужно будет установить gdb.

# Redhat, CentOS, etc
$ yum install gdb

# Ubuntu, Debian, etc
$ apt-get update && apt-get install gdb

затем установите pyrasite.

$ pip install pyrasite

использовать ps или какой-либо другой метод, чтобы найти идентификатор процесса для застрявшего процесса python и запустить pyrasite-shell С ним.

# Assuming process ID is 12345
$ pyrasite-shell 12345

теперь вы должны увидеть Python REPL. Выполните следующее в REPL, чтобы увидеть трассировки стека для всех потоков.

import sys, traceback
for thread_id, frame in sys._current_frames().items():
    print 'Stack for thread {}'.format(thread_id)
    traceback.print_stack(frame)
    print ''

см. мой ответ на это так вопрос используйте продукты.signalstack. Он регистрирует тот же обработчик, что и ответ, который вы уже нашли, во время регистрации продукта. Возможно, для вас это работает лучше.

Если нет, у вас, вероятно, есть проблема ввода-вывода на уровне ОС, и ваша единственная надежда-присоединение gdb к процессу. Переполнение стека поиска для ответов gdb; здесь есть много информации!


вы можете попытаться подключить отладчик к запущенному процессу. См. также этот вопрос.


после беготни по интернету по кругу некоторое время я, наконец, оказался здесь:http://podoliaka.org/2016/04/10/debugging-cpython-gdb/ - подробно описывает, как все части подходят друг к другу. денежная цитата для меня была " gdb / usr/bin / python - p $PID' - имя исполняемого файла требуется для того, чтобы gdb нашел правильные файлы отладочной информации.