multihilos - ¿Hay alguna forma de adjuntar un depurador a un proceso de Python multiproceso?
multihilos en python (8)
Estoy intentando depurar un punto muerto en una aplicación de Python multiproceso después de que se haya bloqueado. ¿Hay alguna manera de adjuntar un depurador para inspeccionar el estado del proceso?
Editar: Estoy intentando esto en Linux, pero sería genial si hubiera una solución multiplataforma. Es Python después de todo :)
¿En qué plataforma estás intentando esto? La mayoría de los depuradores le permiten conectarse a un proceso en ejecución mediante el uso de la identificación del proceso. Puede enviar la identificación del proceso a través del registro o usando algo como el Administrador de tareas. Una vez que se logre esto, será posible inspeccionar los hilos individuales y sus pilas de llamadas.
EDITAR: No tengo ninguna experiencia con GNU Debugger (GDB), que es multiplataforma, sin embargo, encontré este enlace y puede comenzar en el camino correcto. Explica cómo agregar símbolos de depuración (útil para leer los rastreos de pila) y cómo indicar a gdb que se conecte a un proceso en ejecución de python.
Mi experiencia en la depuración de programas de subprocesos múltiples en PyDev (Eclipse en Windows XP) es que los hilos creados con thread.start_new_thread no se pudieron enganchar, pero el hilo creado con threading.Thread podría engancharse. Espero que la información sea útil.
Puede adjuntar un depurador a un proceso de Python multiproceso, pero debe hacerlo en el nivel C. Para darle sentido a lo que sucede, necesita que el intérprete de Python se compile con símbolos. Si no tiene una, debe descargar la fuente de python.org y compilarla usted mismo:
./configure --prefix=/usr/local/pydbg
make OPT=-g
sudo make install
sudo ln -s /usr/local/pydbg/bin/python /usr/local/bin/dbgpy
Asegúrese de que su carga de trabajo se ejecute en esa versión del intérprete. A continuación, puede adjuntarlo con GDB en cualquier momento. La gente de Python ha incluido una muestra ".gdbinit" en su directorio Misc, que tiene algunas macros útiles. Sin embargo, está roto para la depuración de subprocesos múltiples (!). Necesita reemplazar líneas como esta
while $pc < Py_Main || $pc > Py_GetArgcArgv
con lo siguiente:
while ($pc < Py_Main || $pc > Py_GetArgcArgv) && ($pc < t_bootstrap || $pc > thread_PyThread_start_new_thread)
De lo contrario, comandos como pystack
no terminarán en hilos que no sean el hilo principal. Con esto en su lugar, puedes hacer cosas como
gdb> attach <PID>
gdb> info threads
gdb> thread <N>
gdb> bt
gdb> pystack
gdb> detach
y mira lo que está pasando Mas o menos.
Puede analizar qué son los objetos con la macro "pyo". Chris tiene algunos ejemplos en su blog.
Buena suerte.
(¡Shoutout para el blog de Dan para obtener información clave para mí, especialmente la solución de enhebrado!)
Sí, gdb es bueno para la depuración de nivel inferior.
Puede cambiar los hilos con el comando de hilo .
p.ej
(gdb) thr 2
[Switching to thread 2 (process 6159 thread 0x3f1b)]
(gdb) backtrace
....
También puedes consultar depuradores específicos de Python como Winpdb o pydb . Ambas plataformas independientes.
Si te refieres al pydb, no hay forma de hacerlo. Hubo algún esfuerzo en esa dirección: ver el compromiso svn , pero fue abandonado. Supuestamente winpdb lo admite .
Use Winpdb . Es un depurador GPL Python gráfico independiente de la plataforma con soporte para la depuración remota a través de una red, múltiples hilos, modificación del espacio de nombres, depuración incorporada, comunicación encriptada y es hasta 20 veces más rápido que pdb.
caracteristicas:
- Licencia GPL. Winpdb es Software Libre.
- Compatible con CPython 2.3 a 2.6 y Python 3000
- Compatible con wxPython 2.6 a 2.8
- Plataforma independiente, y probado en Ubuntu Gutsy y Windows XP.
- Interfaces de usuario: rpdb2 está basado en la consola, mientras que winpdb requiere wxPython 2.6 o posterior.
Captura de pantalla http://winpdb.org/images/screenshot_winpdb_small.jpg
pdbinject le permite inyectar pdb en un proceso python en ejecución.
El ejecutable pdbinject solo funciona bajo python2, pero también puede inyectarse en python3.
PyCharm IDE permite la conexión a un proceso en ejecución de Python desde la versión 4.0.
Aquí se describe cómo hacer eso.