2010-04-09 14 views
64

Tengo una aplicación multiproceso que es muy estable en todas mis máquinas de prueba y parece ser estable para casi todos mis usuarios (en base a ninguna queja de fallas). Sin embargo, la aplicación falla frecuentemente para un usuario, quien tuvo la amabilidad de enviar informes de fallas. Todos los informes de fallos (~ 10 informes consecutivos) se ven esencialmente idénticas:¿Las excepciones "EXC_BREAKPOINT (SIGTRAP)" están causadas por la depuración de puntos de interrupción?

Date/Time:  2010-04-06 11:44:56.106 -0700 
OS Version:  Mac OS X 10.6.3 (10D573) 
Report Version: 6 

Exception Type: EXC_BREAKPOINT (SIGTRAP) 
Exception Codes: 0x0000000000000002, 0x0000000000000000 
Crashed Thread: 0 Dispatch queue: com.apple.main-thread 

Thread 0 Crashed: Dispatch queue: com.apple.main-thread 
0 com.apple.CoreFoundation  0x90ab98d4 __CFBasicHashRehash + 3348 
1 com.apple.CoreFoundation  0x90adf610 CFBasicHashRemoveValue + 1264 
2 com.apple.CoreText    0x94e0069c TCFMutableSet::Intersect(__CFSet const*) const + 126 
3 com.apple.CoreText    0x94dfe465 TDescriptorSource::CopyMandatoryMatchableRequest(__CFDictionary const*, __CFSet const*) + 115 
4 com.apple.CoreText    0x94dfdda6 TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const + 40 
5 com.apple.CoreText    0x94e00377 TDescriptor::CreateMatchingDescriptors(__CFSet const*, unsigned long) const + 135 
6 com.apple.AppKit    0x961f5952 __NSFontFactoryWithName + 904 
7 com.apple.AppKit    0x961f54f0 +[NSFont fontWithName:size:] + 39 

(.... más texto siguiente)

En primer lugar, pasé mucho tiempo investigando [NSFont fontWithName: Tamaño:]. Pensé que tal vez las fuentes del usuario estaban arruinadas de alguna manera, por lo que [NSFont fontWithName: size:] solicitaba algo inexistente y falla por ese motivo. Agregué un montón de código usando [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] para verificar la disponibilidad de la fuente por adelantado. Lamentablemente, estos cambios no solucionaron el problema.

He notado que olvidé eliminar algunos puntos de interrupción de la depuración, incluidos _NSLockError, [NSException raise] y objc_exception_throw. Sin embargo, la aplicación se creó definitivamente utilizando "Release" como la configuración de compilación activa. Supongo que el uso de la configuración de "Liberar" impide el establecimiento de puntos de interrupción, pero tampoco estoy seguro de cómo funcionan los puntos de interrupción ni si el programa debe ejecutarse desde gdb para que los puntos de interrupción tengan algún efecto.

Mis preguntas son: ¿podría haber dejado los puntos de ruptura establecidos ser la causa de los bloqueos observados por el usuario? Si es así, ¿por qué los puntos de interrupción causan un problema solo para este usuario? Si no, ¿alguien más ha tenido problemas similares con [NSFont fontWithName: size:]?

Probablemente solo trate de eliminar los puntos de interrupción y devolverlos al usuario, pero no estoy seguro de cuánto dinero me queda con ese usuario. Y me gustaría entender más en general si dejar los puntos de interrupción establecidos podría causar un problema (cuando la aplicación se construye utilizando la configuración de "Liberar").

Respuesta

159

Son excepciones "EXC_BREAKPOINT (SIGTRAP)" causadas por la depuración de puntos de interrupción?

Nº revés, en realidad: Un SIGTRAP (trampa traza) hará que el depurador para romper (interrupción) de su programa, de la misma manera un punto de interrupción real lo haría. Pero eso es porque el depurador siempre se rompe en un bloqueo, y un SIGTRAP (como varios otros signals) es un tipo de bloqueo.

Los SIGTRAP son generalmente causados ​​por NSExceptions lanzados, pero no siempre, incluso es posible directamente uno raise.

He notado que olvidé eliminar algunos puntos de interrupción de la depuración, incluidos _NSLockError, [NSException raise] y objc_exception_throw.

Esos no son puntos de interrupción. Dos de ellos son funciones y -[NSException raise] es un método.

¿Quiso decir que estableció los puntos de interrupción en esas funciones y ese método?

que asumen que el uso de la configuración de "Release" impide cualquier ajuste de breakpoints--

Las configuraciones son acumulación configuraciones. Afectan la forma en que Xcode construye sus aplicaciones.

Los puntos de interrupción no son parte de la compilación; los pones en el depurador Solo existen, solo reciben un golpe, y solo detienen tu programa cuando ejecutas tu programa bajo el depurador.

Dado que no son parte de la compilación, no es posible pasar sus puntos de interrupción a un usuario simplemente proporcionándoles el paquete de la aplicación.

No estoy seguro exactamente cómo funcionan los puntos de interrupción ...

Cuando el programa golpea el punto de interrupción, el depurador se rompe (alarmas) su programa, con lo cual se puede examinar el estado del programa y los pasos con cuidado hacia delante para ver cómo el programa sale mal

Dado que es el depurador el que detiene su programa, los puntos de interrupción no tienen efecto cuando no está ejecutando su programa en el depurador.

... o si el programa debe ejecutarse desde gdb para que los puntos de interrupción tengan algún efecto.

Lo hace. Los puntos de interrupción del depurador solo funcionan dentro del depurador.

Mis preguntas son: ¿podría haber dejado los puntos de ruptura establecidos ser la causa de los fallos observados por el usuario?

En primer lugar, como se ha señalado, incluso si estos puntos de interrupción alguna manera hizo llegar transferidos al sistema del usuario, puntos de interrupción sólo son eficaces en el depurador. El depurador no puede detenerse en un punto de interrupción si su programa no se ejecuta bajo el depurador. Es casi seguro que el usuario no esté ejecutando su aplicación bajo el depurador, especialmente dado que obtuvieron un registro de fallas.

Incluso si se quedaron sin su aplicación en el depurador con todos estos puntos de corte establecidos, un punto de interrupción sólo se ve afectado cuando el programa llega a ese punto, por lo que uno de estos puntos de interrupción sólo podía incendio si usted o cacao llamado _NSLockError, -[NSException raise], o objc_exception_throw. Llegar a ese punto no sería la causa del problema, sería un síntoma del problema.

Y si se bloqueó como resultado de uno de los llamados, su registro de bloqueo tendría al menos uno de ellos nombrado en él. No es así

Entonces, esto no estaba relacionado con sus puntos de interrupción (máquina diferente, depurador no involucrado), y no era una excepción de Cocoa, como mencioné, las excepciones de Cacao son una de las causas de los SIGTRAP, pero no son las únicas uno. Encontraste uno diferente.

Si no, ¿alguien más ha tenido problemas similares con [NSFont fontWithName: size:]?

No hay manera de que sepamos si hemos tenido problemas similares porque cortó el registro de bloqueo. No sabemos nada sobre en qué contexto ocurrió el bloqueo.

Lo único que es bueno para cortar es la sección "Imágenes binarias", ya que no tenemos sus paquetes dSYM, lo que significa que no podemos usar esa sección para simbolizar el registro de bloqueo.

Usted, por otro lado, puede. Escribí an app para este propósito; alimentar el registro de fallas, y debe detectar el paquete dSYM automáticamente (mantendrá el paquete dSYM para cada compilación de versión distribuida, ¿no?) y restaurar los nombres de su función y método en el seguimiento de la pila donde aparezcan sus funciones y métodos.

Para obtener más información, consulte el Xcode Debugging Guide.

+2

Wow, gracias por la respuesta completa. • "¿Quiso decir que estableció puntos de interrupción en esas funciones ..." Sí, esto es lo que quise decir. • "Los puntos de interrupción no son parte de la compilación ... Solo existen, solo son afectados, y solo detienen tu programa cuando ejecutas tu programa bajo el depurador" Gracias, esto es exactamente lo que quería saber. • "simboliza el registro de bloqueo ... Escribí una aplicación para este fin" Bonita aplicación. En general, "simbolizo" por pura intuición, ¡pero tu aplicación es una mejor manera! • He llegado a la conclusión de que esto debe tener algún tipo de problema con la fuente del usuario y lo trabajaré desde esa perspectiva. – Dennis

+4

+1 para Symbolicator. –

1

Los puntos de interrupción no se escriben en el binario. Las probabilidades son buenas de que esta persona tenga una instalación de sistema operativo que no funciona. Verifique los registros de la consola para ver si hay mensajes dyld.

+0

Gracias por esta rápida respuesta! Al buscar en Google este problema, me he dado cuenta de que otros tienen EXC_BREAKPOINTS asociados con los mensajes dyld, pero mis registros de fallos no muestran ningún mensaje de dyld. – Dennis

4

Es muy probable que este usuario tenga una fuente corrupta instalada. El seguimiento de la pila definitivamente respalda esa hipótesis, al igual que el hecho de que solo afecta a un usuario.

No hay mucho que pueda hacer en ese caso excepto que el usuario quite la fuente ofensiva, ya que los bloqueos que se producen se producen en el fondo del código de Apple.

Intente hacer que el usuario ejecute una validación de fuente en el Libro de fuentes. Para ello, inicie el Libro de fuentes, haga clic en Todas las fuentes en la lista fuente y luego seleccione todas las fuentes enumeradas. A continuación, puede seleccionar Validar fuentes en el menú Archivo.

+1

Gracias por este consejo sobre Font Book: sé muy poco sobre Fonts y de hecho tuve un momento interesante para validar mis propias fuentes ... Sugeriré que el usuario pruebe esto. – Dennis

+3

+1 para "tuve un momento interesante validando mis propias fuentes" – phlebotinum

1

Tuve el mismo error. Por una razón inexplicable, el punto de interrupción fue el responsable de arrojar la excepción EXC_BREAKPOINT. La solución fue eliminar el punto de interrupción, y luego el código funciona.

EXC_BREAKPOINT es un tipo de excepción que utilizan los depuradores. Cuando establece un punto de interrupción en su código, el compilador inserta una excepción de este tipo en el código ejecutable. Cuando la ejecución llega a ese punto, se lanza la excepción y el depurador lo atrapa. Luego, el depurador muestra su código en la línea "breakpointed". Así es como funcionan los depuradores. Pero en este caso, el depurador no maneja la excepción correctamente y se presenta como un error de excepción regular.

He encontrado este error dos veces en mi vida:

  • uno usando Xcode hace aproximadamente un año.
  • el otro usando Visual C++ hace 15 años.
Cuestiones relacionadas