Отображение трассировки стека из запущенного приложения Python - PullRequest
320 голосов
/ 25 сентября 2008

У меня есть это приложение на Python, которое время от времени зависает, и я не могу найти где.

Есть ли какой-нибудь способ дать интерпретатору Python указание точного кода, который выполняется?

Какая-то трассировка стека на лету?

Похожие вопросы:

Ответы [ 25 ]

10 голосов
/ 26 января 2012

Взгляните на модуль faulthandler, новый в Python 3.3. A faulthandler backport для использования в Python 2 доступен для PyPI.

7 голосов
/ 29 августа 2011

В Solaris вы можете использовать pstack (1). Нет необходимости вносить изменения в код Python. например.

# pstack 16000 | grep : | head
16000: /usr/bin/python2.6 /usr/lib/pkg.depotd --cfg svc:/application/pkg/serv
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:282 (_wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:295 (wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:242 (block) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/_init_.py:249 (quickstart) ]
[ /usr/lib/pkg.depotd:890 (<module>) ]
[ /usr/lib/python2.6/threading.py:256 (wait) ]
[ /usr/lib/python2.6/Queue.py:177 (get) ]
[ /usr/lib/python2.6/vendor-packages/pkg/server/depot.py:2142 (run) ]
[ /usr/lib/python2.6/threading.py:477 (run)
etc.
6 голосов
/ 16 апреля 2012

Я некоторое время искал решение для отладки своих потоков, и я нашел его здесь благодаря haridsv. Я использую слегка упрощенную версию с использованием traceback.print_stack ():

import sys, traceback, signal
import threading
import os

def dumpstacks(signal, frame):
  id2name = dict((th.ident, th.name) for th in threading.enumerate())
  for threadId, stack in sys._current_frames().items():
    print(id2name[threadId])
    traceback.print_stack(f=stack)

signal.signal(signal.SIGQUIT, dumpstacks)

os.killpg(os.getpgid(0), signal.SIGQUIT)

Для своих нужд я также фильтрую темы по имени.

6 голосов
/ 24 июня 2013

Если вы работаете в системе Linux, используйте удивительную gdb с расширениями отладки Python (может быть в пакете python-dbg или python-debuginfo). Это также помогает с многопоточными приложениями, приложениями с графическим интерфейсом и модулями C.

Запустите вашу программу с:

$ gdb -ex r --args python <programname>.py [arguments]

Это инструктирует gdb подготовить python <programname>.py <arguments> и r un it.

Теперь, когда ваша программа зависает, переключитесь на консоль gdb, нажмите Ctr + C и выполните:

(gdb) thread apply all py-list

См. пример сеанса и дополнительную информацию здесь и здесь .

3 голосов
/ 06 апреля 2012

Я собрал несколько инструментов, которые подключаются к работающему процессу Python и внедряют некоторый код для получения оболочки Python.

Смотрите здесь: https://github.com/albertz/pydbattach

3 голосов
/ 29 января 2009

Стоит взглянуть на Pydb , «расширенную версию отладчика Python, свободно основанную на наборе команд gdb». Он включает диспетчеры сигналов, которые могут позаботиться о запуске отладчика при отправке указанного сигнала.

Проект Summer of Code 2006 года рассматривал добавление функций удаленной отладки в pydb в модуле под названием mpdb .

2 голосов
/ 01 мая 2014

pyringe - это отладчик, который может взаимодействовать с запущенными процессами python, трассировкой стека печати, переменными и т. Д. Без какой-либо предварительной настройки.

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

1 голос
/ 16 января 2019

Как отладить любую функцию в консоли :

Создать функцию , где вы используете pdb.set_trace () , затем функция, которую вы хотите отладить.

>>> import pdb
>>> import my_function

>>> def f():
...     pdb.set_trace()
...     my_function()
... 

Затем вызвать созданную функцию:

>>> f()
> <stdin>(3)f()
(Pdb) s
--Call--
> <stdin>(1)my_function()
(Pdb) 

Счастливая отладка:)

1 голос
/ 27 апреля 2013

Для этого можно использовать PuDB , отладчик Python с интерфейсом curses. Просто добавьте

from pudb import set_interrupt_handler; set_interrupt_handler()

к вашему коду и используйте Ctrl-C, когда вы хотите сломать. Вы можете продолжить с c и повторить попытку несколько раз, если пропустите это и хотите повторить попытку.

1 голос
/ 25 сентября 2008

Нет способа подключиться к работающему процессу Python и получить разумные результаты. То, что я делаю, если процессы заблокированы, - это перехватывает связь и пытается выяснить, что именно происходит.

К сожалению, часто strace является наблюдателем, который "фиксирует" условия гонки, так что вывод там тоже бесполезен.

...