Python: можно ли подключить консоль к запущенному процессу?
Я просто хочу посмотреть состояние процесса, можно ли подключить консоль к процессу, чтобы я мог вызывать функции внутри процесса и видеть некоторые глобальные переменные.
Лучше процесс работает без ущерба (конечно, производительность может немного уменьшиться)
Ответы
Ответ 1
Если у вас есть доступ к исходному коду программы, вы можете легко добавить эту функцию.
См. Рецепт 576515: Debugging a running python process by interrupting and providing an interactive prompt (Python)
Цитата:
Это дает код, позволяющий любому python программа, которая использует ее для прерывается в текущей точке и обменивается с помощью обычного питона интерактивная консоль. Это позволяет locals, globals и связанная программа государства, подлежащего расследованию, а также вызов произвольных функций и классы.
Чтобы использовать, процесс должен импортировать модуль и вызов listen() в любой точке во время запуска. Чтобы прервать это процесс, script может быть запущен непосредственно, давая идентификатор процесса процесс для отладки в качестве параметра.
Другая реализация примерно такой же концепции обеспечивается rconsole. Из документации:
rconsole - удаленная консоль Python с автоматическим завершением, которое может быть используется для проверки и модификации пространство имен запущенного script.
Чтобы вызвать в script do:
from rfoo.utils import rconsole
rconsole.spawn_server()
Чтобы установить из оболочки, выполните:
$ rconsole
Примечание по безопасности: слушатель rconsole началось с spawn_server() принять любое локальное соединение и может поэтому небезопасно использовать в общих хостинг или подобные среды!
Ответ 2
Это прервет ваш процесс (если вы не запустите его в потоке), но вы можете использовать модуль code
для запуска консоли Python:
import code
code.interact()
Это будет заблокировано, пока пользователь не выйдет из интерактивной консоли, выполнив exit()
.
Модуль code
доступен, по крайней мере, для Python v2.6, возможно, для других.
Я использую этот подход в сочетании с сигналами для моей работы с Linux (для Windows, см. ниже). Я пощелкаю это в верхней части моих сценариев Python:
import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())
И затем запустите его из оболочки с помощью kill -SIGUSR2 <PID>
, где <PID>
- это идентификатор процесса. Затем этот процесс останавливает все, что он делает, и представляет консоль:
Python 2.6.2 (r262:71600, Oct 9 2009, 17:53:52)
[GCC 3.4.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
В общем оттуда я загружу серверный компонент удаленного отладчика, например отличный WinPDB.
Windows не является POSIX -компьютерной ОС и поэтому не предоставляет те же сигналы, что и Linux. Однако Python v2.2 и выше выставляют сигнал, специфичный для Windows SIGBREAK
(запускается нажатием CTRL
+ Pause/Break
). Это не мешает нормальной работе CTRL
+ C
(SIGINT
), и поэтому это удобная альтернатива.
Поэтому переносимая, но слегка уродливая версия выше:
import code
import signal
signal.signal(
vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"),
lambda sig, frame: code.interact()
)
Преимущества такого подхода:
- Нет внешних модулей (все стандартные материалы Python)
- Едва потребляет все ресурсы до запуска (2x импорт)
Вот код, который я использую в моей рабочей среде, которая загрузит серверную часть WinPDB (если она доступна) и вернется к открытию консоли Python.
# Break into a Python console upon SIGUSR1 (Linux) or SIGBREAK (Windows:
# CTRL+Pause/Break). To be included in all production code, just in case.
def debug_signal_handler(signal, frame):
del signal
del frame
try:
import rpdb2
print
print
print "Starting embedded RPDB2 debugger. Password is 'foobar'"
print
print
rpdb2.start_embedded_debugger("foobar", True, True)
rpdb2.setbreak(depth=1)
return
except StandardError:
pass
try:
import code
code.interact()
except StandardError as ex:
print "%r, returning to normal program flow" % ex
import signal
try:
signal.signal(
vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR1"),
debug_signal_handler
)
except ValueError:
# Typically: ValueError: signal only works in main thread
pass
Ответ 3
Используйте пиразит-оболочку. Я не могу поверить, что это работает так хорошо, но это так. " Дайте ему pid, получите оболочку ".
$ sudo pip install pyrasite
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # If YAMA activated, see below.
$ pyrasite-shell 16262
Pyrasite Shell 2.0
Connected to 'python my_script.py'
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> globals()
>>> print(db_session)
>>> run_some_local_function()
>>> some_existing_local_variable = 'new value'
Это запускает оболочку python с доступом к переменным globals() и locals() для выполняющегося процесса python и другим замечательным вещам.
Только проверял это лично на Ubuntu, но, похоже, обслуживает OSX.
Адаптировано из этого ответа.
Примечание. Линия, отключающая свойство ptrace_scope
необходима только для ядер/систем, которые были созданы с CONFIG_SECURITY_YAMA
. Будьте осторожны с ptrace_scope в чувствительных средах, потому что это может привести к определенным уязвимостям безопасности. Подробнее см. Здесь.
Ответ 4
Почему бы просто не использовать модуль pdb? Он позволяет остановить script, проверить значения элементов и выполнить код за строкой. И поскольку он построен на интерпретаторе Python, он также предоставляет функции, предоставляемые классическим интерпретатором. Чтобы использовать его, просто поместите эти 2 строки в свой код, где вы хотите остановить и проверить его:
import pdb
pdb.set_trace()
Ответ 5
Здесь описывается другая возможность, не добавляя материал в скрипты python:
https://wiki.python.org/moin/DebuggingWithGdb
К сожалению, это решение также требует некоторой предусмотрительности, по крайней мере, в той мере, в какой вам нужно использовать версию python с отладочными символами в ней.
Ответ 6
Используя PyCharm, я получал отказ подключиться к процессу в Ubuntu. Исправить это - отключить YAMA. Для получения дополнительной информации см. askubuntu
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope