python - Volcando stacktraces de todos los hilos activos
multithreading plone (6)
2.4. Demasiado. Desde Python 2.5 en adelante hay sys._current_frames()
.
Pero puedes probar threadframe . Y si el archivo make le da problemas, puede probar este setup.py para threadframe
Estoy tratando de volcar una lista de todos los subprocesos activos, incluida la pila actual de cada uno. Puedo obtener una lista de todos los subprocesos usando threading.enumerate (), pero no puedo encontrar una manera de llegar a la pila desde allí.
Antecedentes: una aplicación de Zope / Plone enloquece de vez en cuando, consume el 100% de la CPU y necesita reiniciarse. Tengo la sensación de que es un bucle que no termina correctamente, pero no puedo reproducirlo en el entorno de prueba para su verificación. Logré registrar un controlador de señales que puede activarse desde el exterior, por lo que puedo activar algún código tan pronto como vuelva a ocurrir la situación. Si pudiera volcar el seguimiento de pila para todos los subprocesos activos, eso me daría una pista de lo que está mal. El agujero se ejecuta en python 2.4 ...
Cualquier idea sobre cómo localizar situaciones como estas son apreciadas :)
Saludos, Chriss
Como señala jitter en una respuesta anterior, sys._current_frames()
te da lo que necesitas para v2.5 +. Para el perezoso, el siguiente fragmento de código funcionó para mí y puede ayudarte:
print >> sys.stderr, "/n*** STACKTRACE - START ***/n"
code = []
for threadId, stack in sys._current_frames().items():
code.append("/n# ThreadID: %s" % threadId)
for filename, lineno, name, line in traceback.extract_stack(stack):
code.append(''File: "%s", line %d, in %s'' % (filename,
lineno, name))
if line:
code.append(" %s" % (line.strip()))
for line in code:
print >> sys.stderr, line
print >> sys.stderr, "/n*** STACKTRACE - END ***/n"
Hay una receta aplicable en ASPN . Puede usar threading.enumerate()
para obtener todos los tid, luego simplemente llame a _async_raise () con alguna excepción adecuada para forzar un seguimiento de la pila.
Para Python 3.3 y faulthandler.dump_traceback()
posteriores, hay faulthandler.dump_traceback()
.
El siguiente código produce un resultado similar, pero incluye el nombre del hilo y podría mejorarse para imprimir más información.
for th in threading.enumerate():
print(th)
traceback.print_stack(sys._current_frames()[th.ident])
print()
Solo por razones de integridad, Products.LongRequestLogger es súper útil para identificar cuellos de botella y, para hacerlo, descarga pilas de paquetes en intervalos específicos.
Al usar Zope, desea instalar Products.signalstack
o mr.freeze ; ¡Estos fueron diseñados para este propósito!
Envíe una señal USR1 a su servidor Zope e inmediatamente volcará los seguimientos de la pila de todos los hilos a la consola. Hará esto incluso si todos los hilos de Zope están bloqueados.
Bajo el capó, estos paquetes usan de manera indirecta threadframes
; para las versiones 2.5 y superiores de Python, cuando no use Zope, puede crear la misma funcionalidad utilizando la función sys._current_frames()
para acceder a los marcos de pila por hilo.
A partir de Zope 2.12.5 esta funcionalidad está integrada en Zope, y ya no es necesario instalar paquetes adicionales.