Solo quiero ver el estado del proceso, si es posible adjuntar una consola al proceso, para poder invocar funciones dentro del proceso y ver algunas de las variables globales.
Es mejor que el proceso se esté ejecutando sin verse afectado (por supuesto, el rendimiento puede disminuir un poco)
Respuestas:
Si tiene acceso al código fuente del programa, puede agregar esta funcionalidad con relativa facilidad.
Consulte la receta 576515 :
Debugging a running python process by interrupting and providing an interactive prompt (Python)
Citar:
Rconsole proporciona otra implementación de aproximadamente el mismo concepto . De la documentación:
from rfoo.utils import rconsole rconsole.spawn_server()
fuente
rfoo._rfoo.EofError: 0
Esto interrumpirá su proceso (a menos que lo inicie en un hilo), pero puede usar el
code
módulo para iniciar una consola Python:import code code.interact()
Esto se bloqueará hasta que el usuario salga de la consola interactiva ejecutando
exit()
.El
code
módulo está disponible al menos en Python v2.6, probablemente en otros.Tiendo a usar este enfoque en combinación con señales para mi trabajo con Linux (para Windows, ver más abajo). Pongo esto en la parte superior de mis scripts de Python:
import code import signal signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())
Y luego desencadenarlo desde un shell con
kill -SIGUSR2 <PID>
, donde<PID>
está el ID del proceso. Luego, el proceso detiene lo que esté haciendo y presenta una consola: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) >>>
Generalmente, desde allí cargaré el componente del lado del servidor de un depurador remoto como el excelente WinPDB .
Windows no es un sistema operativo compatible con POSIX , por lo que no proporciona las mismas señales que Linux. Sin embargo, Python v2.2 y superior exponen una señal específica de Windows
SIGBREAK
(activada presionandoCTRL
+Pause/Break
). Esto no interfiere con el funcionamiento normalCTRL
+C
(SIGINT
), por lo que es una alternativa útil.Por lo tanto, una versión portátil, pero un poco fea, de lo anterior es:
import code import signal signal.signal( vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"), lambda sig, frame: code.interact() )
Ventajas de este enfoque:
Aquí está el código que utilizo en mi entorno de producción que cargará el lado del servidor de WinPDB (si está disponible) y volverá a abrir una consola 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
fuente
Utilice pyrasite-shell . No puedo creer que funcione tan bien, pero lo hace. " Dale un pid, consigue un caparazón ".
$ 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'
Esto lanza el shell de Python con acceso a las variables globals () y locals () de ese proceso de Python en ejecución, y otras cosas maravillosas.
Solo probé esto personalmente en Ubuntu, pero parece ser compatible con OSX también.
Adaptado de esta respuesta .
Nota: La línea que desactiva la
ptrace_scope
propiedad solo es necesaria para los kernels / sistemas que se han construido conCONFIG_SECURITY_YAMA
on. Tenga cuidado al jugar con ptrace_scope en entornos sensibles porque podría introducir ciertas vulnerabilidades de seguridad. Consulte aquí para obtener más detalles.fuente
¿Por qué no utilizar simplemente el módulo pdb ? Le permite detener un script, inspeccionar los valores de los elementos y ejecutar el código línea por línea. Y dado que se basa en el intérprete de Python, también proporciona las funciones proporcionadas por el intérprete clásico. Para usarlo, simplemente coloque estas 2 líneas en su código, donde desea detenerlo e inspeccionarlo:
import pdb pdb.set_trace()
fuente
Aquí se describe otra posibilidad, sin agregar cosas a los scripts de Python:
https://wiki.python.org/moin/DebuggingWithGdb
Desafortunadamente, esta solución también requiere algo de previsión, al menos en la medida en que necesite usar una versión de Python con símbolos de depuración.
fuente
Usando PyCharm, estaba obteniendo un error al conectarme al proceso en Ubuntu. La solución para esto es desactivar YAMA. Para obtener más información, consulte askubuntu
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
fuente