Debungging e Autorelease

iPad, iPhone, MacOSX Soft! Commenta l'articolo


Il bug più ricorrente nello sviluppo di applicazione per iPhone è EXC_BAD_ACCESS in un autorelease pool.
Vediamo cosa dobbiamo fare per scovarlo.

Gli strumenti necessari sono la classe NSZombie e l’applicazione malloc_history lanciata tramite terminale.
Supponiamo di avere il seguente pezzo di codice:

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  NSData* data = [NSData dataWithBytes:"asklaskdxjgr" length:12];

  [data release];
  [pool release];

Il metodo dataWithBytes manda un messaggio di autorelease all’oggetto, quindi non abbiamo bisogno del metodo release. Quando viene lanciato l’autorelease il sistema crasha, perchè l’oggetto non è più allocato.
Che cosa bisogna fare in questo caso?
In XCode 3.2 bisogna andare su Project ->Edit Active Executable “nome dell App” e nella sezione “Variables to be set in to environment ” aggiungere le seguenti variabili d’ambiente:

NSDebugEnabled
  NSZombieEnabled
  MallocStackLogging

Con NSZombieEnabled abilitato, Cocoa setta un puntatore ad un oggetto isa la classe NSZombie e solleva un’eccezione quando un’oggetto ha un retainCount uguale a 0, invece di deallocarlo.

 2011-03-10 13:01:38.644 autoreleasebug[3939] *** *** Selector 'release'
  sent to dealloced instance 0xa4e10 of class NSConcreteData.

Sul terminale si può lanciare “malloc_history <pid> <address>” :

[soft@host193 Frameworks]$ malloc_history 3939 0xa4e10

  Call [2] [arg=32]: thread_a0000dec |0x1000 | start | _start | main |
  +[NSData dataWithBytes:length:] | NSAllocateObject | object_getIndexedIvars |
  malloc_zone_calloc 

Vuol dire che è stato fatto un doppio release sull’oggetto [NSData dataWithBytes:length:]

Compreso tutto? Buon lavoro.

Scrivi un Commento

Home | Graffiti e Disegni | Educazione | Chi siamo | Blog | Progetti | Contatti
RSS Feed Comments RSS Accedi