У меня есть это приложение Python, которое время от времени зависает, и я не могу найти где.
Есть ли какой-нибудь способ дать интерпретатору Python указание точного кода, который выполняется?
Какая-то трассировка стека на лету?
Смежные вопросы:
У меня есть это приложение Python, которое время от времени зависает, и я не могу найти где.
Есть ли какой-нибудь способ дать интерпретатору Python указание точного кода, который выполняется?
Какая-то трассировка стека на лету?
Смежные вопросы:
Ответы:
У меня есть модуль, который я использую для таких ситуаций - когда процесс будет работать долго, но иногда застревает по неизвестным и невоспроизводимым причинам. Это немного странно, и работает только на Unix (требует сигналов):
Для использования просто вызовите функцию listen () в какой-то момент, когда ваша программа запускается (вы можете даже вставить ее в site.py, чтобы все программы Python ее использовали), и позволить ей работать. В любой момент отправьте процессу сигнал SIGUSR1, используя kill или в python:
Это приведет к тому, что программа перейдет к консоли Python в точке, в которой она находится в данный момент, показывая трассировку стека и позволяя вам манипулировать переменными. Используйте control-d (EOF) для продолжения работы (хотя учтите, что вы, вероятно, прервете любой ввод-вывод и т. Д. В точке, о которой вы сигнализируете, чтобы он не был полностью ненавязчивым).
У меня есть другой скрипт, который делает то же самое, за исключением того, что он связывается с запущенным процессом по каналу (для отладки фоновых процессов и т. Д.). Это немного большой, чтобы разместить здесь, но я добавил его как рецепт кулинарной книги питона .
источник
faulthandler
модуль (и его обратный порт, найденный в PyPI) для обработчика сигналов уровня C, который будет печатать стек Python без необходимости реагирования цикла интерпретатора.Предложение об установке обработчика сигналов хорошее, и я им часто пользуюсь. Например, bzr по умолчанию устанавливает обработчик SIGQUIT, который вызывает
pdb.set_trace()
немедленное перетаскивание вас в приглашение pdb . ( Точную информацию смотрите в источнике модуля bzrlib.breakin .) С помощью pdb вы можете не только получить текущую трассировку стека, но и проверить переменные и т. Д.Однако иногда мне нужно отлаживать процесс, в котором у меня не было предвидения, чтобы установить обработчик сигналов. В Linux вы можете присоединить к процессу gdb и получить трассировку стека python с помощью некоторых макросов gdb. Поместите http://svn.python.org/projects/python/trunk/Misc/gdbinit в
~/.gdbinit
, то:gdb -p
PID
pystack
К сожалению, это не совсем надежно, но работает большую часть времени.
Наконец, присоединение
strace
может дать вам хорошее представление о том, что делает процесс.источник
python-dbg
). Без этих символов вы, похоже, не получите много полезной информации.Unable to locate python frame
к каждой командеЯ почти всегда имею дело с несколькими потоками, и основной поток обычно не делает много, поэтому самое интересное - сбросить все стеки (что больше похоже на дамп Java). Вот реализация, основанная на этом блоге :
источник
Получение трассировки стека неподготовленной программы на Python, работающей на стандартном Python без отладочных символов, может быть выполнено с помощью Pyrasite . В Ubuntu Trusty для меня это сработало:
(Шляпа на @Albert, ответ на который содержал указатель на это, среди других инструментов.)
источник
dump_stacks.py
было простоimport traceback; traceback.print_stack()
traceback -l
дает вам список предопределенных скриптов Python, которые вы можете использовать, иdump_stacks.py
является одним из них. Если вы используете свое собственное (например, для записи трассировки стека в файл), может быть целесообразно использовать другое имя.apt-get install gdb python-dbg
(или эквивалентный) перед запуском пиразита, иначе он молча потерпит неудачу. Работает как шарм в противном случае!Вы также можете отформатировать трассировку стека, см. Документацию .
Редактировать : чтобы имитировать поведение Java, как предлагает @Douglas Leeder, добавьте это:
к коду запуска в вашем приложении. Затем вы можете распечатать стек, отправив
SIGUSR1
запущенному процессу Python.источник
Модуль traceback имеет несколько приятных функций, среди которых: print_stack:
источник
import traceback; f = open('/tmp/stack-trace.log', 'w') traceback.print_stack(file=f) f.close()
Вы можете попробовать модуль обработчика ошибок . Установите его используя
pip install faulthandler
и добавьте:в начале вашей программы. Затем отправьте SIGUSR1 вашему процессу (например
kill -USR1 42
:) для отображения трассировки Python всех потоков в стандартный вывод. Прочтите документацию для получения дополнительных опций (например: войти в файл) и других способов отображения трассировки.Модуль теперь является частью Python 3.3. Для Python 2 см. Http://faulthandler.readthedocs.org/
источник
Что мне действительно помогло, так это совет spiv (за который я бы проголосовал и прокомментировал бы, если бы у меня были очки репутации), чтобы получить трассировку стека из неподготовленного процесса Python. За исключением того, что он не работал, пока я не изменил скрипт gdbinit . Так:
загрузите http://svn.python.org/projects/python/trunk/Misc/gdbinit и вставьте его в
~/.gdbinit
отредактируйте его, изменив[править: больше не нужно; связанный файл уже имеет это изменение по состоянию на 2010-01-14]PyEval_EvalFrame
наPyEval_EvalFrameEx
Прикрепить GDB:
gdb -p PID
Получить трассировку стека Python:
pystack
источник
No symbol "co" in current context.
Я бы добавил это в качестве комментария к ответу haridsv , но мне не хватает репутации, чтобы сделать это:
Некоторые из нас все еще привязаны к версии Python старше 2.6 (требуется для Thread.ident), поэтому я получил код, работающий в Python 2.5 (хотя и без отображения имени потока), как таковой:
источник
python -dv yourscript.py
Это заставит интерпретатор работать в режиме отладки и даст вам представление о том, что делает интерпретатор.
Если вы хотите интерактивно отлаживать код, вы должны запустить его так:
python -m pdb yourscript.py
Это говорит интерпретатору python запускать ваш скрипт с модулем "pdb", который является отладчиком python, если вы запустите его так, что интерпретатор будет выполняться в интерактивном режиме, очень похожем на GDB
источник
Взгляните на
faulthandler
модуль, новый в Python 3.3.faulthandler
Портировать для использования в Python 2 доступно на PyPI.источник
В Solaris вы можете использовать pstack (1). Нет необходимости вносить изменения в код Python. например.
источник
pstack
которая делает то же самоеЕсли вы работаете в системе Linux, используйте замечательные
gdb
расширения Python для отладки (могут быть в виде пакетаpython-dbg
илиpython-debuginfo
пакета). Это также помогает с многопоточными приложениями, приложениями GUI и модулями C.Запустите вашу программу с:
Это инструктирует
gdb
подготовитьpython <programname>.py <arguments>
и снятьr
его.Теперь, когда ваша программа зависает, переключитесь на
gdb
консоль, нажмите Ctr+Cи выполните:Смотрите пример сессии и больше информации здесь и здесь .
источник
Некоторое время я искал решение для отладки своих потоков, и я нашел его здесь благодаря haridsv. Я использую слегка упрощенную версию, использующую traceback.print_stack ():
Для своих нужд я также фильтрую темы по имени.
источник
Стоит взглянуть на Pydb , «расширенную версию отладчика Python, свободно основанную на наборе команд gdb». Он включает диспетчеры сигналов, которые могут позаботиться о запуске отладчика при отправке указанного сигнала.
Проект Summer of Code 2006 года рассматривал добавление функций удаленной отладки в pydb в модуле с именем mpdb .
источник
Я собрал воедино какой-то инструмент, который подключается к работающему процессу Python и внедряет некоторый код, чтобы получить оболочку Python.
Смотрите здесь: https://github.com/albertz/pydbattach
источник
pyrasite
отлично!Это можно сделать с отличным пи-шпионом . Это профилировщик выборки для программ Python , поэтому его работа заключается в подключении к процессам Python и выборке их стеков вызовов. Следовательно,
py-spy dump --pid $SOME_PID
это все, что вам нужно сделать, чтобы сбросить стеки вызовов всех потоков в$SOME_PID
процессе. Как правило, ему нужны расширенные привилегии (для чтения памяти целевого процесса).Вот пример того, как это выглядит для многопоточного приложения Python.
источник
pyringe - это отладчик, который может взаимодействовать с запущенными процессами Python, трассировкой стека печати, переменными и т. д. без какой-либо предварительной настройки.
Хотя в прошлом я часто использовал решение для обработки сигналов, в некоторых средах по-прежнему бывает трудно воспроизвести проблему.
источник
pyrasite
работал как шарм для меня.Нет способа подключиться к работающему процессу Python и получить разумные результаты. То, что я делаю, если процессы блокируются, это просто цепляется за попытки и пытается выяснить, что именно происходит.
К сожалению, часто страус является наблюдателем, который «фиксирует» условия гонки, так что результат там тоже бесполезен.
источник
Для этого вы можете использовать PuDB , отладчик Python с интерфейсом curses. Просто добавь
к вашему коду и используйте Ctrl-C, когда вы хотите сломать. Вы можете продолжить
c
и снова сломать несколько раз, если вы пропустите это и хотите повторить попытку.источник
Я нахожусь в лагере GDB с расширениями Python. Следуйте https://wiki.python.org/moin/DebuggingWithGdb , что означает
dnf install gdb python-debuginfo
илиsudo apt-get install gdb python2.7-dbg
gdb python <pid of running process>
py-bt
Также рассмотрим
info threads
иthread apply all py-bt
.источник
Traceback (most recent call first): Python Exception <class 'gdb.error'> No frame is currently selected.: Error occurred in Python command: No frame is currently selected.
при запускеpy-bt
вgdb
?sudo
.gdb pyton <pid>
Мне тоже нужно было бежать как Судо.Как отладить любую функцию в консоли :
Создайте функцию, в которой вы используете pdb.set_trace () , затем функцию, которую вы хотите отладить.
Затем вызовите созданную функцию:
Удачной отладки :)
источник
Я не знаю ничего похожего на ответ java на SIGQUIT , поэтому вам, возможно, придется встроить его в свое приложение. Может быть, вы могли бы создать сервер в другом потоке, который мог бы получить трассировку стека в ответ на какое-либо сообщение?
источник
используйте модуль проверки.
stack (context = 1) Возвращает список записей для стека выше кадра вызывающего.
Я нахожу это действительно полезным.
источник
В Python 3 pdb автоматически установит обработчик сигнала при первом использовании c (ont (inue)) в отладчике. После этого нажмите Control-C, и вы снова окажетесь там. В Python 2 приведен однострочный текст, который должен работать даже в относительно старых версиях (протестировано в 2.7, но я проверил исходники Python до 2.4 и все выглядело нормально):
pdb стоит изучить, если вы потратите какое-то время на отладку Python. Интерфейс немного тупой, но должен быть знаком любому, кто использовал подобные инструменты, такие как gdb.
источник
В случае, если вам нужно сделать это с помощью uWSGI, в него встроен Python Tracebacker, и достаточно просто включить его в конфигурации (номер присваивается имени каждому работнику):
Сделав это, вы можете распечатать трассировку, просто подключившись к сокету:
источник
В тот момент, когда код запускается, вы можете вставить этот небольшой фрагмент, чтобы увидеть хорошо отформатированный отпечаток трассировки стека. Предполагается, что у вас есть папка
logs
в корневом каталоге вашего проекта.источник