Contenedor de excepciones para la aplicación Carbon C en OSX
-
03-07-2019 - |
Pregunta
¿Cómo puedo detectar y manejar de manera eficiente los fallos de segmentación de C en una aplicación OSX Carbon?
Fondo: Estoy haciendo una aplicación de OSX Carbon. Debo llamar a una función de biblioteca de un tercero. Debido a problemas de subprocesos, la función puede bloquearse ocasionalmente, generalmente porque se está actualizando a sí misma desde un subproceso, y tiene algún puntero o controlador obsoleto internamente cuando lo consulto desde otro. La función es una caja negra para mí. Quiero poder llamar a la función pero poder " capturar " Si se ha estrellado y suministre un retorno alternativo. En Windows, puedo usar el simple compilador de Visual C e Intel C __try {} y __except.
/* Working Windows Example */
__try { x=DangerousFunction(y);}
__except(EXCEPTION_EXECUTE_HANDLER) {x=0.0;} /* whups, func crashed! */
Estoy tratando de hacer el mismo tipo de catch-crash para OSX. Estoy usando C puro en una aplicación muy grande. Llamo a la función millones de veces por segundo, por lo que la eficiencia también es muy importante. (¡Impresionante, la sobrecarga de Windows __try () es inmensamente pequeña!)
Esto es lo que he experimentado con:
1) Excepciones de C ++. No estoy seguro de si las excepciones de C ++ detectan los fallos de segfault. Y mi aplicación es actualmente C. Podría probar wrappers y #ifdefs para convertirlo en C ++, pero esto es mucho trabajo para la aplicación, y no creo que las excepciones de C ++ atrapen el bloqueo.
2) señal + setjump + longjmp. Pensé que esto funcionaría ... es para lo que está diseñado. Pero configuré mi controlador de errores SEGV [¡de hecho lo configuré para cada señal!] Y nunca se llama durante el bloqueo. Puedo probar manualmente (y tener éxito) al llamar a raise (SEGV). Pero los accidentes no parecen realmente llamarlo. Creo que las aplicaciones CFM NO tienen acceso a las señales BSD completas, solo un subconjunto, y que las aplicaciones Mach son necesarias para la Cosa Real.
3) MPSetExceptionHandler. No bien documentado Intenté establecer un controlador. Se compiló y corrió, pero no detectó la falla de seguridad.
Solución
¿Está seguro de que no obtendrá un SIGBUS en lugar de un SIGSEGV?
Lo siguiente detecta a SIGBUS como causado al intentar escribir en la ubicación de memoria 0:
cristi:tmp diciu$ cat test.c
#include <signal.h>
static void sigac(int sig)
{
printf("sig action here, signal is %d\n", sig);
exit(1);
}
int main()
{
(void)signal(SIGSEGV, sigac);
(void)signal(SIGBUS, sigac);
printf("Raising\n");
strcpy(0, "aaksdjkajskd|");
}
cristi:tmp diciu$ ./a.out
Raising
sig action here, signal is 10