Проверьте, что делает запущенный процесс: выведите на стек трассировку неструктурированной программы Python
Есть ли способ в Linux, чтобы проверить, что делает работающий процесс демона Python? То есть без инструментирования кода и без его завершения? Желательно, чтобы я получил название модуля и номер строки в нем, который запущен в данный момент.
Обычные средства отладки, такие как strace, pstack и gdb, не очень полезны для кода Python. Большинство стековых фреймов просто содержат функции из кода интерпретатора, такие как PyEval_EvalFrameEx и PyEval_EvalCodeEx, это не дает вам никаких намеков на то, что в.py-файле выполняется выполнение.
8 ответов
Некоторые ответы в разделе Отображение трассировки стека из запущенного приложения Python применимы в этой ситуации:
Пиразит (это был тот, который работал для меня):
$ sudo pip install pyrasite $ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope $ sudo pyrasite 16262 dump_stacks.py # dumps stacks to stdout/stderr of the python program
- pydbattach - не может заставить это работать, но хранилище https://github.com/albertz/pydbattach содержит указатель на другие инструменты
- По сообщениям, pstack печатает стек Python на Solaris
py-spy (https://github.com/benfred/py-spy) имеет несколько полезных инструментов для проверки запущенных процессов Python. В частности,
py-spy dump
напечатает трассировку стека (включая функцию, файл и строку) для каждого потока.
winpdb позволяет вам присоединиться к работающему процессу python, но для этого вы должны запустить процесс python следующим образом:
rpdb2 -d -r script.py
Затем после установки пароля:
A password should be set to secure debugger client-server communication.
Please type a password:mypassword
Вы можете запустить winpdb для Файл> Присоединить (или Файл> Отсоединить) к процессу.
В системах POSIX, таких как Linux, вы можете использовать старый добрый GDB, см.
- https://t37.net/debug-a-running-python-process-without-printf.html и
- https://wiki.python.org/moin/DebuggingWithGdb
Существует также превосходная среда разработки PyCharm (доступна бесплатная версия сообщества), которая может подключаться к работающему процессу Python прямо из среды IDE с использованием Pdb 4 под капотом, см. Эту запись в блоге:
Вы можете использовать madbg (мной). Это отладчик Python, который позволяет подключаться к работающей программе Python и отлаживать ее в текущем терминале. Это похоже наpyrasite
а также pyringe
, но новее, не требует GDB и использует IPython
для отладчика (что означает цвета и автозаполнение).
Чтобы увидеть трассировку стека запущенной программы, вы можете запустить:
madbg attach <pid>
И в оболочке отладчика введите:bt
Иптрас делает именно это. Это позволяет вам присоединиться к работающему процессу Python и показать выполняемые в данный момент функции, такие как strace
делает для системных вызовов. Вы можете назвать это так:
vagrant@precise32:/vagrant$ sudo python lptrace -p $YOUR_PID
fileno (/usr/lib/python2.7/SocketServer.py:438)
meth (/usr/lib/python2.7/socket.py:223)
fileno (/usr/lib/python2.7/SocketServer.py:438)
meth (/usr/lib/python2.7/socket.py:223)
...
Обратите внимание, что для работы требуется gdb, который доступен не на каждом сервере.
Можно отлаживать Python с помощью gdb. См. Главу 22: Поддержка gdb в Руководстве разработчика Python.
Например, в Debian с Python 3.7:
# apt-get install gdb python3.7-dbg
# gdb
(gdb) source /usr/share/gdb/auto-load/usr/bin/python3.7-gdb.py
(gdb) attach <PID>
(gdb) py-bt
Вы также можете использовать для этого сателлу . Приятным побочным эффектом будет то, что каждая локальная переменная в каждом кадре стека будет распечатана. Код будет таким:
from satella.instrumentation import Traceback
import sys
for frame_no, frame in sys._current_frames().items():
sys.stderr.write("For stack frame %s" % (frame_no,))
tb = Traceback(frame)
tb.pretty_print()
sys.stderr.write("End of stack frame dump\n")