Pregunta

he podido registrar mi propio puerto mach a mach excepciones de captura en mis aplicaciones y funciona muy bien cuando me meta 32 bits. Sin embargo, cuando me meta 64 bits, mi excepción catch_exception_raise() manejador es llamado, pero el conjunto de códigos de excepción que se pasa al controlador de 32 bits de ancho. Con ello se espera en una versión de 32 bits, pero no en 64 bits.

En el caso donde cojo EXC_BAD_ACCESS el primer código es el número de error y el segundo código debe ser la dirección de la falla. Dado que el segundo código es de 32 bits de ancho las altas 32 bits de la dirección de error de 64 bits está truncado.

He encontrado una bandera en <mach/exception_types.h> me puede pasar en task_set_exception_ports() llamada MACH_EXCEPTION_CODES que a partir de mirar las fuentes de Darwin parece controlar el tamaño de los códigos pasa al controlador. Todo apunta a que está destinado a ser ored con el comportamiento pasado a task_set_exception_ports().

Sin embargo cuando hago esto y desencadenar una excepción, mi puerto Mach se notificó, llamo exc_server() pero mi manejador nunca se llamó, y cuando el mensaje de respuesta se envía de vuelta al núcleo consigo el comportamiento de excepción por defecto.

Me estoy apuntando el SDK 10.6.

Realmente deseo que Apple podría documentar estas cosas mejor. Cualquiera tiene alguna idea?

¿Fue útil?

Solución

Bueno, lo he descubierto.

Para excepciones mach mango, hay que registrarse un puerto mach para las excepciones que interesa. A continuación, esperar a que llegue un mensaje en el puerto en otro hilo. Cuando llega un mensaje, se llama a exc_server() cuya aplicación es proporcionada por System.library. exec_server() lleva el mensaje que llegó y llama a uno de tres manipuladores que debe proporcionar. catch_exception_raise(), catch_exception_raise_state() o catch_exception_raise_state_identity() dependiendo de los argumentos que se pasan a task_set_exception_ports(). Esta es la forma en que se hace para las aplicaciones de 32 bits.

Para aplicaciones de 64 bits, el método de 32 bits todavía funciona, pero los datos que se pasan a usted en su manejador puede ser truncado a 32 bits. Para obtener 64 bits de datos pasados ??a sus manipuladores requiere un poco de trabajo extra que no es muy sencillo y por lo que yo puedo decir no muy bien documentado. Me topé con la solución al observar las fuentes de BGF.

En lugar de llamar exc_server() cuando un mensaje llega al puerto, hay que mach_exc_server() llamada en lugar. Los controladores también tienen que tener diferentes nombres como catch_mach_exception_raise() así, catch_mach_exception_raise_state() y catch_mach_exception_raise_state_identity(). Los parámetros para los controladores son los mismos que sus contrapartes de 32 bits. El problema es que mach_exc_server() no está previsto que el camino es exc_server(). Para obtener la aplicación para mach_exc_server() requiere el uso de la soldadura MIG (Mach Interface Generator) utilidad. MIG toma un archivo de definición de interfaz y genera un conjunto de ficheros fuente que incluyen una función de servidor que despachos mach mensajes a los controladores suministrados por el usuario. Los 10,5 y 10,6 SDK incluyen un archivo de definición MIG de los mensajes de excepción y generará la función mach_exc_server(). A continuación, incluya los archivos de origen que se generan en su proyecto y entonces usted está listo para salir.

Lo bueno es que si se dirigen a 10.6+ (y tal vez 10.5) se puede utilizar el mismo control de excepciones para los de 32 y 64 bits. Incluye o el comportamiento excepción con MACH_EXCEPTION_CODES al configurar los puertos de excepción. Los códigos de excepción vendrá a través como valores de 64 bits, pero se puede truncar a 32 bits en su construcción 32 bits.

Tomé el archivo mach_exc.defs y copié en mi directorio de origen, abrí un terminal y utilicé el comando mig -v mach_exc.defs. Esto genera mach_exc.h, mach_excServer.c y mach_excUser.c. a continuación, he incluido los archivos en mi proyecto, agregó la declaración correcta para la función de servidor en mi archivo de origen y puesto en práctica mis manejadores. a continuación, he construido mi aplicación y era bueno para ir.

Bueno, esto no es la mejor descripción, pero espero que ayude a alguien más ahí fuera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top