Resolver símbolos en un fichero de errores de iOS (Symbolicate)

Cuando se cuelga una aplicación de iOS, el usuario puede mandarnos información sobre ello y así podremos ver cuál es el error.

 

¿Qué debemos hacer?

Lo primero, antes de distribuir el .ipa deberíamos haber guardado el fichero .dSYM asociado a él.

No es posible generarle más adelante. Aunque nos movamos al mismo commit en el que la app fue generada y tengamos exactamente el mismo código, el fichero .dSYM generado no te servirá.

Esto es lo que dice la documentación de Apple sobre ello:

The Debug Symbol file and application binary are tied together on a per-build-basis by the build UUID. A new UUID is generated for each build of your application and uniquely identifies that build. Even if a functionally-identical executable is rebuilt from the same source code, with the same compiler settings, it will have a different build UUID. Debug Symbol files from subsequent builds, even from the same source files, will not interoperate with binaries from other builds.

Que significa: El fichero .dSYM y el binario están unidos por el UDID de compilación. Un nuevo UDID es generado para cada compilación e identifica de manera única esa compilación. Incluso un mismo ejecutable, con el mismo código es generado, tendrá un UDID distinto. Por eso motivo, el dSYM file de otras compilaciones no podrán operar con los binarios de otras operaciones.

 

¿Qué debe hacer el cliente cuando la aplicación se queda colgada o crashea?

Necesitaremos que el cliente obtenga el fichero de errores del dispositivo, cuya extensión es .ips.

Donde está localizado este fichero varía dependiendo de la versión. Para dispositivo que tengan la versión 10 o superior está en Ajustes → Privacidad → Análisis → Datos del análisis.

El nombre del fichero contiene el nombre de nuestra app y la fecha.

 

Si habías guardado el fichero .dSYM, puedes seguir leyendo esta sección. Si no, puedes ir a la siguiente sección del artículo un poco más abajo.

¿Cuál es el siguiente paso?

Una vez que el cliente nos ha mandado el fichero .ips, debemos modificar la extensión a .crash.

Si lo abrimos, podemos ver que contiene direcciones de memoria.

Ejemplo:

Last Exception Backtrace:

(0x1fd1c7ea0 0x1fc399a40 0x1fd0ce674 0x1fdb46c64 0x1fdb46bcc 0x10227193c 0x10227257c 0x1fcc02484 0x1fcba46d8 0x1fdf7fa14 0x1fd1581cc 0x1fd15814c 0x1fd157a84 0x1fd1528fc 0x1fd1521cc 0x1ff3c9584 0x22a24d054 0x1022847cc 0x1fcc12bb4)

Ahora debemos resolver los símbolos de este fichero (symobolicate). Esto es transformar las direcciones en métodos del código fuente. 

Este es el comando que debemos usar: 

symbolicatecrash MyApp_2019-05-09_Device.crash MyApp.app.dSYM

Si funciona, nos devolverá el contenido del fichero “traducido”.

Ejemplo:

Last Exception Backtrace:

0   CoreFoundation                0x1fd1c7ea0 __exceptionPreprocess + 228

1   libobjc.A.dylib               0x1fc399a40 objc_exception_throw + 55

2   CoreFoundation                0x1fd0ce674 +[NSException raise:format:] + 115

3   Foundation                    0x1fdb46c64 -[NSPlaceholderString initWithFormat:locale:arguments:] + 123

4   Foundation                    0x1fdb46bcc +[NSString stringWithFormat:] + 67

5   MyApp                   0x10227193c +[ABNotifier showNoticeAlertForNoticesWithPaths:] + 39228 (ABNotifier.m:693)

6   MyApp                   0x10227257c __ABNotifierReachabilityDidChange_block_invoke + 42364 (ABNotifier.m:836)

7   libdispatch.dylib             0x1fcc02484 _dispatch_client_callout + 15

8   libdispatch.dylib             0x1fcba46d8 _dispatch_once_callout + 27

9   SystemConfiguration           0x1fdf7fa14 reachPerformAndUnlock + 539

10  CoreFoundation                0x1fd1581cc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 23

11  CoreFoundation                0x1fd15814c __CFRunLoopDoSource0 + 87

12  CoreFoundation                0x1fd157a84 __CFRunLoopDoSources0 + 259

13  CoreFoundation                0x1fd1528fc __CFRunLoopRun + 1039

14  CoreFoundation                0x1fd1521cc CFRunLoopRunSpecific + 435

15  GraphicsServices              0x1ff3c9584 GSEventRunModal + 99

16  UIKitCore                     0x22a24d054 UIApplicationMain + 211

17 MyApp                   0x1022847cc main + 116684 (main.m:15)

18  libdyld.dylib                 0x1fcc12bb4 start + 3

Entonces siguiendo esta traza, puede que encontremos la solución al problema que causó que la aplicación se colgase.

 

Pero, ¿qué pasa si no has guardado el fichero .dSYM?

Si no habíamos guardado el fichero .dSYM, la primera cosa que deberíamos hacer es empezar a guardarlo.

Ahora, veremos algunos trucos que pueden ayudar a “traducir” el fichero.

Aunque para ello necesitaremos usar el mismo ordenador con que se genero el binario, porque si no, no va a funcionar.

 

Importar el fichero a xCode

Para ello, necesitaremos hacer un par de cosas primero: Modificar la extensión a .crash y conectar un dispositivo de iOS al ordenador. 

Entonces, con xCode abierto, pincharemos en la pestaña Window del menú y seleccionaremos Devices.

Ahora seleccionaremos el dispositivo conectado para ver el panel informativo. Haz click en el botón “View Device Logs” .

En esta sección podemos seleccionar la pestaña de “All logs” tab y arrastrar el fichero al panel izquierdo. Pulsar sobre el botón derecho y seleccionar “Re-symbolicate log”.

Si esto funciona, podemos intentar buscar la solución al problema que generó el crash.

Si no, puedes intentar otra opción.

 

Usar el comando symbolicatecrash sin archivo .dSYM

Normalmente el comando se usa asi:

symbolicatecrash MyApp_2019-05-09_Device.crash MyApp.app.dSYM

Pero podemos omitir el último argumento, el que se refiere al fichero .dSYM:

symbolicatecrash app.crash

Como en el consejo anterior, esto puede funcionar o no. Si funciona, ahora con el fichero “traducido” puedes comprobar dónde falló la aplicación.

 

Error al ejecutar symbolicatecrash

Si al ejecutar el comando symbolicatecrash, recibes un mensaje de error de que el commando no se encuentra.

Debes ejecutar el siguiente comando, para encontrar la ruta absoluta: 

find /Applications/Xcode.app name symbolicatecrash type f

y seleccionar la ruta completa al comando.

Si entonces, recibes el mensaje de error de que DEVELOPER_DIR no se encuentra, debes ejecutar:

export DEVELOPER_DIR=‘/Applications/Xcode.app/Contents/Developer’

 

¿Has tenido suerte? ¿te han servido de algo estos trucos?

De todas maneras, recuerda archivar el archivo .dSYM a partir de ahora.

Además, puede pensar en integrar un servicio de monitorización de errores. De eso podemos hablar en otro artículo.

 

Articulos relacionados

Firmado iOS Parte 1

Creando una librería compartida para iOS de forma sencilla

Distribución continua Ad-Hoc de una aplicación iOS con Bitrise

 

Deja un comentario

Responsable » Solidgear.
Finalidad » Gestionar los comentarios.
Legitimación » Tu consentimiento.
Destinatarios » Los datos que me facilitas estarán ubicados en los servidores SolidgearGroup dentro de la UE.
Derechos » Podrás ejercer tus derechos, entre otros, a acceder, rectificar, limitar y suprimir tus datos.

Envíando este formulario aceptas la política de privacidad.

¿Necesitas una estimación?

Calcula ahora