2009-12-23 22 views
5

Sé que, dado el contexto suficiente, se podría esperar usar constructivamente (es decir, recuperar) a partir de una condición de segfault.¿Hay algún punto para atrapar "segfault"?

Pero, ¿vale la pena el esfuerzo? En caso afirmativo, ¿en qué situación?

Respuesta

14

Realmente no puede esperar recuperarse de una segfault. Puede detectar que sucedió y, si es posible, eliminar el estado específico de la aplicación relevante, pero no puede continuar el proceso. Esto es porque (entre otros)

  • El hilo que falló no puede continuarse, por lo que sus únicas opciones son longjmp o terminar el hilo. Ninguno de los dos es seguro en la mayoría de los casos.
  • De cualquier manera, es posible dejar un mutex/bloqueo en un estado bloqueado que hace que otros hilos que esperar para siempre
  • Incluso si eso no sucede, puede filtrarse recursos
  • Incluso si usted no hace bien de esas cosas, el hilo que segfaulted pudo haber dejado el estado interno de la aplicación inconsistente cuando falló. Un estado interno inconsistente podría causar errores de datos o más mal comportamiento, posteriormente, lo que provoca más problemas que simplemente dejar de fumar

Así que, en general, no hay ningún punto en atrapar y hacer otra cosa que terminar el proceso de una manera bastante abrupta.No tiene sentido tratar de escribir datos (importantes) en el disco, o continuar haciendo otro trabajo útil. Existe algún punto para eliminar el estado de los registros, que son muchas aplicaciones, y luego dejarlo.

Una cosa posiblemente útil para hacer podría ser ejecutar su propio proceso, o tener un proceso de vigilancia que se reinicia en caso de un bloqueo. (NB: el ejecutor no siempre tiene un comportamiento bien definido si su proceso tiene> 1 hilo)

+0

+1: respuesta maravillosa ... muchas gracias. – jldupont

+0

Un buen resumen, pero no estoy de acuerdo por el motivo que mencioné en mi respuesta; hay momentos en los que se está haciendo algo específico que puede causar una segfault, y "recuperación" no es un problema. –

1

Para registrar un seguimiento de pila de bloqueo, por ejemplo.

+0

+1: Debería haber enumerado esta posibilidad en la pregunta (es decir, ya había considerado esta situación): así que es mi culpa por no hacerlo. – jldupont

6

a Segmentation Fault está realmente accediendo a la memoria a la que no tiene permiso de acceso (ya sea porque no está mapeada, no tiene permisos, dirección virtual no válida, etc.).

Según el motivo subyacente, es posible que desee atrapar y manejar el error de segmentación. Por ejemplo, si su programa recibe una dirección virtual no válida, puede registrar esa segfault y luego hacer algún control de daños.

Un segfault no significa necesariamente que el montón del programa está dañado. Leer una dirección no válida (por ejemplo, un puntero nulo) puede dar como resultado una segfault, pero eso no significa que el montón esté dañado. Además, una aplicación puede tener varios montones dependiendo del tiempo de ejecución de C.

+0

@kervin: ¿qué tipo de control de daños? el montón podría ser un montón de basura en ese momento – Alon

+0

@Alon: Editado para responder a su pregunta. Un segfault no significa necesariamente que el montón está dañado. Además, su controlador no tiene que estar usando el mismo montón o espacio de direcciones que se ve afectado por segfault. – kervin

+5

Las fallas de segmentación han sido utilizadas por los algoritmos de recolección de basura para establecer una barrera al final del heap, cuando se accede y se entrega sigsegv, es una indicación de que se necesita hacer un gc. – Christian

13

Varias de las razones:

  1. para proporcionar más información específica de la aplicación para depurar un accidente. Por ejemplo, me colapsé en la etapa 3 procesando el archivo 'x'.
  2. Para probar si ciertas regiones de memoria son accesibles. Esto fue principalmente para satisfacer una API para un sistema integrado. Intentaríamos escribir en la región de memoria y detectar la segfault que nos decía que la memoria era de solo lectura.
  3. La segfault suele originarse con una señal de la MMU, que el sistema operativo utiliza para intercambiar páginas de memoria si es necesario. Si el sistema operativo no tiene esa página de memoria, entonces reenvía la señal a la aplicación.
+0

+1: .... gracias. – jldupont

+0

@Chris: tu respuesta es genial (desde mi punto de vista) pero solo puedo aceptar una por desgracia. Muchas gracias por tu contribución. – jldupont

0

No, creo que es una pérdida de tiempo: un error seg indica que hay algo mal en el código, y será mejor que lo encuentre al examinar un volcado del núcleo y/o su código fuente. La única vez que traté de atrapar una falla seg me llevó a una sala de espejos que podría haber evitado simplemente pensando en el código fuente. Nunca más.

+0

+1: gracias por el consejo educado. – jldupont

5

Existen técnicas muy avanzadas que uno podría implementar detectando un error de segmentación, si sabe que la falla de segmentación no es un error. Por ejemplo, puede proteger páginas para que no pueda leer de ellas, y luego atrapar el SIGSEGV para realizar un comportamiento "mágico" antes de que finalice la lectura. (Consulte Tomasz Węgrzanowski "Segfaulting own programs for fun and profit" para ver un ejemplo de lo que podría hacer, pero generalmente la sobrecarga es bastante alta, por lo que no vale la pena hacerlo).

Un principio similar se aplica a capturar una excepción de instrucción ilegal (generalmente en el kernel) para emular un instrucción que no está implementada en su procesador.

+0

+1: gracias por esto. – jldupont

Cuestiones relacionadas