Fork me on GitHub

Pagine

mercoledì 29 maggio 2013

Rendere più leggibili i crash logs di iOs con symbolicatecrash

Chiunque sviluppi su iOs si è sicuramente scontrato con la risoluzione dei crash delle proprie app, sia in fase di test 'interno', sia con le applicazioni già presenti in AppStore.

Tutti i dispositivi iOs salvano i log di tutti i crash, proprio per aiutare  lo sviluppatore a scoprirne le cause, ma non sempre questi log sono immediatamente comprensibili.




Vediamo un esempio di crashlog per un'ipotetica applicazione MyApp:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib           0x313fec98 0x313fc000 + 11416
1   MyApp                     0x00019c12 0x1000 + 101394
2   MyApp                     0x0000a1cc 0x1000 + 37324
3   MyApp                     0x0000c474 0x1000 + 46196
4   libdispatch.dylib         0x33e9d8e0 0x33e92000 + 47328
5   libdispatch.dylib         0x33e991ee 0x33e92000 + 29166
6   CoreFoundation            0x3568e934 0x35616000 + 493876
7   CoreFoundation            0x3561eebc 0x35616000 + 36540
8   CoreFoundation            0x3561edc4 0x35616000 + 36292
9   GraphicsServices          0x343cd418 0x343c9000 + 17432
10  GraphicsServices          0x343cd4c4 0x343c9000 + 17604
11  UIKit                     0x3608ad62 0x3605c000 + 191842
12  UIKit                     0x36088800 0x3605c000 + 182272
13  MyApp                     0x000024ec 0x1000 + 5356
14  MyApp                     0x000024ac 0x1000 + 5292

e qui arriva il bello: per ogni entry è presente la riga di codice dove si è presentato il problema, ma l'oggetto corrispondente viene rappresentato solamente con un codice esadecimale.

Per capire qualcosa di più ci viene in aiuto symbolicatecrash, un tool da linea di comando presente in XCode che permette di collegare i codici esadecimali alle classi corrispondenti.

Ovviamente è indispensabile archiviare ogni build che viene distribuita, in quando symbolicatecrash ha necessità tanto del log quanto della build che lo ha generato.

symbolicatecrash è prelevabile da
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash
Per comodità, consiglio di creare un alias per richiamare il comando senza dover specificare ogni volta il path completo: modificate (o create, se non presente) il file .bash_profile nella vostra home directory e aggiungete al suo interno la seguente riga:
alias symbolicate="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash -v"
salvate, uscite e riavviate il terminale.

Una volta configurato l'alias possiamo procedere all'interpretazione del log:
symbolicate "MyApp_2013-05-24-170900-iPhone.crash" "MyApp.app"
il comando restituirà sullo standard output il log con questo formato:
Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib        0x33b24c98 objc_msgSend + 16
1   MyApp                  0x00019c12 -[TwoLineNavBarTitleView setLine2:] 
                                       (TwoLineNavBarTitleView.m:43)
2   MyApp                  0x0000a1cc -[ListViewController 
                                       listModelDidFinishQueryingForRadius:] 
                                       (ListViewController.m:160)
3   MyApp                  0x0000c474 __45-[ListViewModel 
                                       filterParksBasedOnCategories]
                                       (ListViewModel.m:129)
4   libdispatch.dylib      0x33d108e0 _dispatch_call_block_and_release + 4
5   libdispatch.dylib      0x33d0c1ee _dispatch_main_queue_callback + 306
6   CoreFoundation         0x3039f934 __CFRunLoopRun + 1328
7   CoreFoundation         0x3032febc CFRunLoopRunSpecific + 224
8   CoreFoundation         0x3032fdc4 CFRunLoopRunInMode + 52
9   GraphicsServices       0x35571418 GSEventRunModal + 108
10  GraphicsServices       0x355714c4 GSEventRun + 56
11  UIKit                  0x358c7d62 -[UIApplication _run] + 398
12  UIKit                  0x358c5800 UIApplicationMain + 664
13  MyApp                  0x000024ec main (main.m:14)
14  MyApp                  0x000024ac 0x1000 + 5292

sicuramente molto più comprensibile!