¿Las excepciones "EXC_BREAKPOINT (SIGTRAP)" son causadas por puntos de interrupción de depuración?

82

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 (basado en que no hay quejas de fallas). Sin embargo, la aplicación se bloquea con frecuencia para un usuario, que tuvo la amabilidad de enviar informes de bloqueo. Todos los informes de fallos (~ 10 informes consecutivos) parecen esencialmente idénticos:

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

(... sigue más texto)

Primero, pasé mucho tiempo investigando [NSFont fontWithName: size:]. Pensé que tal vez las fuentes del usuario estaban estropeadas de alguna manera, por lo que [NSFont fontWithName: size:] estaba solicitando algo que no existía y fallaba por esa razón. Agregué un montón de código usando [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] para verificar la disponibilidad de fuentes por adelantado. Lamentablemente, estos cambios no solucionaron el problema.

Ahora me he dado cuenta de que olvidé eliminar algunos puntos de interrupción de depuración, incluidos _NSLockError, [NSException raise] y objc_exception_throw. Sin embargo, la aplicación definitivamente se creó utilizando "Release" como configuración de compilación activa. Supongo que el uso de la configuración "Release" evita la configuración de puntos de interrupción, pero, de nuevo, no estoy seguro de cómo funcionan exactamente los puntos de interrupción o si el programa debe ejecutarse desde gdb para que los puntos de interrupción tengan algún efecto.

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

Probablemente solo intentaré eliminar los puntos de interrupción y enviar de vuelta al usuario, pero no estoy seguro de cuánta moneda me queda con ese usuario. Y me gustaría entender de manera más general si dejar los puntos de interrupción establecidos podría causar un problema (cuando la aplicación se crea con la configuración de "Versión").

Dennis
fuente

Respuestas:

188

¿Las excepciones "EXC_BREAKPOINT (SIGTRAP)" son causadas por puntos de interrupción de depuración?

No. Al revés, en realidad: un SIGTRAP (trampa de rastreo) hará que el depurador interrumpa (interrumpa) su programa, de la misma manera que lo haría un punto de interrupción real. Pero eso se debe a que el depurador siempre se rompe en caso de bloqueo, y un SIGTRAP (como varias otras señales ) es un tipo de bloqueo.

Los SIGTRAP generalmente son causados ​​por NSExceptions que se lanzan, pero no siempre, incluso es posible generar uno directamente .

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

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

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

Supongo que el uso de la configuración "Release" evita la configuración de puntos de interrupción:

No.

Las configuraciones son configuraciones de construcción . Afectan la forma en que Xcode crea sus aplicaciones.

Los puntos de interrupción no forman parte de la construcción; los configura en el depurador. Solo existen, solo son golpeados y solo detienen su programa cuando lo ejecuta bajo el depurador.

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

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

Cuando su programa llega al punto de interrupción, el depurador interrumpe (interrumpe) su programa, después de lo cual puede examinar el estado del programa y avanzar con cuidado para ver si el programa falla.

Dado que es el depurador el que detiene su programa, los puntos de interrupción no tienen efecto cuando no está ejecutando su programa bajo 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: ¿el haber dejado los breakpoints establecidos podría ser la causa de las caídas observadas por el usuario?

No.

Primero, como se señaló, incluso si estos puntos de interrupción se transfirieron de alguna manera al sistema del usuario, los puntos de interrupción solo son efectivos 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 porque obtuvieron un registro de bloqueo.

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 los alcances del programa de ese momento, por lo que uno de estos puntos de interrupción sólo podían fuego si usted o cacao llamada _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 la llamada de uno de ellos, su registro de bloqueos tendría al menos uno de ellos nombrado. No es así.

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

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

No hay forma de que podamos saber si los problemas que hemos tenido son similares porque cortó el registro de fallos. No sabemos nada sobre el contexto en el que ocurrió el accidente.

Lo único que es bueno recortar 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 fallas.

Tú, por otro lado, puedes. Escribí una aplicación para este propósito; alimente el registro de fallos, y debería detectar el paquete dSYM automáticamente (usted está guardando el paquete dSYM para cada versión de versión que distribuya, ¿verdad?) y restaurar sus funciones y nombres de métodos en el seguimiento de la pila dondequiera que aparezcan sus funciones y métodos.

Para obtener más información, consulte la Guía de depuración de Xcode .

Peter Hosey
fuente
3
Vaya, gracias por la respuesta completa. • "¿Querías decir que estableciste 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 golpeados y solo detienen su programa cuando ejecuta su programa bajo el depurador" Gracias, esto es exactamente lo que quería saber. • "simbolizar el registro de fallos ... escribí una aplicación para este propósito" Buena aplicación. En general, "simbolizo" por pura intuición, ¡pero su 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 trabajaré desde esa perspectiva.
Dennis
7

Es muy probable que este usuario tenga instalada una fuente corrupta. 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 hacer que el usuario elimine la fuente ofensiva, ya que los bloqueos que ocurren tienen lugar en el fondo del código de Apple.

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

Rob Keniger
fuente
1
Gracias por este consejo sobre el Libro de fuentes. Sé muy poco sobre las fuentes y de hecho lo pasé muy bien validando mis propias fuentes ... Sugeriré que el usuario pruebe esto.
Dennis
0

Los puntos de interrupción no se escriben en el binario. Es muy probable que esta persona tenga una instalación de sistema operativo defectuosa. Compruebe los registros de la consola para ver si hay mensajes dyld.

Azeem.Butt
fuente
¡Gracias por esta rápida respuesta! Al buscar en Google este problema, he notado que otros tienen EXC_BREAKPOINTS asociados con mensajes dyld, pero mis registros de fallos no muestran ningún mensaje de dyld.
Dennis
0

Yo tenía el mismo error. Por una razón inexplicable, el punto de interrupción fue el responsable de lanzar 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 la detecta. Luego, el depurador muestra su código en la línea de "puntos de interrupción". 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.

Encontré este error dos veces en mi vida:

  • uno que usaba Xcode hace aproximadamente un año.
  • el otro usando Visual C ++ hace unos 15 años.
Veladan
fuente
Es extraño que obtuve este error sin ningún punto de interrupción.
Kelin
No digo que este error se produzca solo con puntos de interrupción: EXC_BREAKPOINT puede suceder por varias razones. Lo que estoy explicando son un par de casos muy poco frecuentes en los que un punto de interrupción genera una excepción no controlada.
Veladan