Determinar si un subproceso de python falla

Estoy escribiendo un progtwig que califica a los estudiantes, y como estoy seguro de que puedes imaginar, a veces fallan en la segmentación. El problema que tengo es que cuando la segmentación de los progtwigs de los estudiantes falla, no hay ninguna indicación de que haya ocurrido eso.

proc = subprocess.Popen(student_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.stdout, self.stderr = proc.communicate() self.returncode = proc.returncode 

Recojo el código stderr, stdout y retorno del subproceso, pero si la segmentación del progtwig falla, stderr está vacío, stdout está vacío y el código de retorno es -11. Ahora puedo buscar el código de salida -11 y asumir que si ese es el código de retorno, hubo una falla de segmentación, pero tampoco hay nada que impida que el código de un estudiante tenga -11 como código de retorno solo porque el estudiante tenía ganas de volver. -11.

¿Cómo saber si un segmentado de subproceso falla, en lugar de simplemente tener ganas de regresar -11? Realmente no me importa mucho lo que está en stderr y stdout, y con ese fin he visto una cantidad de publicaciones, incluida esta, que tratan de recoger la salida, pero no me importa mucho la salida, aunque sería bueno obtener la cadena “Falla de segmentación” de stderr, pero lo que realmente necesito es una forma de decir definitivamente lo que sucedió con el subproceso.

Bueno, de hecho, en UNIX, un proceso que intenta devolver -11 normalmente terminará devolviendo un entero positivo en su lugar. Esto se debe a que el estado de retorno de la serie de funciones de wait es en realidad un conjunto de campos de bits, con un campo para la señal que finalizó el proceso y un campo separado para el valor de retorno. Python decodifica el valor de retorno de wait de estos campos de bits.

En la mayoría de los sistemas, estos campos están sin firmar y tienen un tamaño de 8 bits, por lo que probablemente verá algo como esto:

 >>> import subprocess >>> subprocess.Popen(['python','-c','import os; os.kill(os.getpid(),11)']).wait() -11 >>> subprocess.Popen(['python','-c','exit(-11)']).wait() 245 

En el primer caso, el proceso “seguridades” (matándose a sí mismo con SIGSEGV) y, por lo tanto, wait devuelve -11. En este último caso, el proceso sale con un código de retorno de -11, y el valor de wait resultante es 245 (256-11). Por lo tanto, puede estar seguro de que cualquier valor de retorno negativo de wait debe representar una señal fatal, en lugar de un retorno normal. Tenga en cuenta, sin embargo, que los procesos pueden suicidarse para falsificar un error fatal.