Je travaille sur un crash de l'iPhone un peu compliqué, et il semble que le coupable soit un NSString sorti prématurément. J'ai activé NSZombiesEnabled et je peux voir que NSString est un zombie au moment du crash. Cependant, je ne peux pas déterminer quand l'objet est libéré/désalloué - j'ai parcouru mon code en recherchant les messages de version envoyés à cet objet et j'ai défini des points d'arrêt à ces endroits, mais ils ne sont pas touchés. Je suppose qu'il s'agit peut-être d'un problème de threading ou d'autorelease étant donné sa nature intermittente, mais est-il possible de se connecter à l'exécution d'objectif-c via le débogueur Xcode pour indiquer le point exact où un objet est publié? Ou y a-t-il une meilleure façon de diagnostiquer ce problème?Comment savoir quand l'objet est envoyé message de libération?
Répondre
Si vous pouvez reproduire le crash dans le simulateur, vous pouvez utiliser l'outil malloc_history
. (Il a une page de manuel.) Vous devez définir certaines variables d'environnement: normalement, je les configure via l'écran "Modifier l'exécutable actif" dans le volet Arguments, puis j'utilise les cases à cocher pour les activer/désactiver. Assurez-vous de les désactiver avant de déboguer sur l'appareil; Si activé, le programme essaiera d'écrire à /tmp
que le sandbox n'autorise pas.
Je trouve cet outil combiné avec NSZombie
me permet de traquer les erreurs alloc/prématurée-libération/accès-après-dealloc. Une fois que NSZombie
signale l'accès à un objet désalloué, vous pouvez utiliser malloc_history
pour déterminer quand l'objet a été alloué. Cela me met normalement sur la voie de l'élaboration où le problème est.
Un autre outil que j'ai trouvé inestimable est clang du projet LLVM. Il est encore en développement, mais ils produisent régulièrement des binaires pour MacOS-X qui me semblent assez stables. En particulier, il comprend la politique de gestion de la mémoire Cocoa. Son utilisation est aussi simple que:
% cd ${DIRECTORY_CONTAINING_XCODE_PROJECT}
% xcodebuild clean
% scan-build -V xcodebuild
Cela va faire une génération complète de votre projet et de produire un rapport énumérant toutes les erreurs évidentes (y compris fiascos-comptage de référence) que l'outil trouve.
je ne pourrais pas être penser droit, mais avez-vous envisagé d'ajouter une version et dealloc sur votre classe
- (void) release
{
NSLog(@"Releasing");
[super release];
}
- (void) dealloc
{
NSLog(@"Deallocating");
[super dealloc];
}
Incorporer le commentaire de Ben Gotow d'utiliser une catégorie obj-c, vous vous retrouvez avec ceci:
@interface NSString (release)
-(void) release;
@end
@implementation NSString (release)
-(void) release
{
NSLog(@"NSString Released!");
[super release];
}
@end
Devrait avoir mentionné, ceci est un NSString. – drewh
Que diriez-vous de sous-classer NSString: http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/doc/uid/20000154-397865 - la technique ci-dessus serait alors encore travailler. –
Je crois que vous pourriez créer une catégorie Obj-C qui remplace les fonctions release et dealloc de NSString sans sous-classe ... Le sous-classement serait probablement très compliqué. –
Pourriez-vous implémenter dealloc() et mettre un point d'arrêt dedans? En regardant la trace de la pile à partir de ce point, vous devriez savoir où et comment elle est libérée.
Ceci est un zombie NSString, donc je ne peux pas faire un point d'arrêt dans dealloc. – drewh
vous pouvez dire au fournisseur de dtrace
de déclencher votre sonde chaque fois que -[NSString release]
est appelé, mais cela impliquera un petit hackery méchant. Les NSStrings ne sont pas réellement des NSStrings mais sont toutes des sous-classes, en raison de la façon dont la classe est implémentée en tant que cluster de classe. Maintenant, cela ne nous gênera pas; ce sera est que NSString
n'a pas son propre -release
:-). Vous pouvez cependant fournir le vôtre dans une catégorie.
Vous pouvez également indiquer à quelle instance de NSString
va se casser, vous pouvez simplement définir un point d'arrêt conditionnel sur -[NSObject dealloc]
avec self==myInstance
.
Une autre façon de procéder.Assurez-vous d'activer NSZombie afin qu'il indique l'adresse mémoire de l'objet qui obtient la version supplémentaire. Ensuite, exécutez avec Performance Tool-> Allocations d'objets. Cela amènera des instruments. Regardez le journal de la console fourni par Xcode organizer. Une fois que vous obtenez le crash, recherchez l'adresse de la mémoire dans les instruments. Vous verrez l'historique complet de mallocs/libres sur cet objet, ainsi que des liens directement dans votre code.
- 1. Comment savoir quand Windows est inactif
- 2. Comment savoir quand Big O est Logarithmique?
- 3. comment savoir quand une réponse dde est terminée?
- 4. Comment savoir quand une animation UITableView est terminée?
- 5. .NET: Comment savoir quand la sérialisation est terminée?
- 6. Comment savoir jQuery: Quand le chargement est prêt, montrez-le?
- 7. Comment savoir quand le swf principal est complètement chargé?
- 8. Comment savoir quand un élément XAML est terminé chargement
- 9. Comment savoir quand le dernier OutputDataReceived est arrivé?
- 10. Comment indiquer qu'un message envoyé à MPMediaPlayer a expiré?
- 11. Comment savoir quand un winform est chargé par Process.Start?
- 12. Comment savoir quand un programme est ouvert avec javascript?
- 13. Comment puis-je déterminer si un type de message est envoyé ou posté?
- 14. Comment savoir quand nosetest s'exécute par programme
- 15. Comment savoir quand un contrôle va être caché
- 16. UITextView de l'iPhone - comment savoir quand un texte que vous ajoutez est hors de vue
- 17. Delphi: Comment savoir quand un TEdit change de taille?
- 18. rappel Javascript pour savoir quand une image est chargée
- 19. JavaScript: Savoir quand une image est complètement chargée
- 20. Comment savoir quand j'ai arrêté de faire défiler un TScrollBar?
- 21. Comment savoir quand il y a trop de connexions SQL?
- 22. Comment puis-je savoir si un message MAPI donné est entrant ou sortant?
- 23. SQL Server Express DB est 'in recovery' - comment détecter/savoir quand il est
- 24. Comment savoir si une boucle de message MFC est déjà en cours d'exécution?
- 25. Héritage ordre de libération?
- 26. Message CMExit Delphi non envoyé lorsque le dialogue modal est fermé?
- 27. Comment puis-je savoir quand la dernière ligne d'une source de données ListView est liée?
- 28. Comment savoir quand le processus de génération d'index Lucene est terminé
- 29. Comment savoir quand envoyer une réponse 304 non modifiée
- 30. wpf savoir quand le modèle a changé
Je seconde en utilisant CLang. Cela vous permettra souvent de trouver des choses que vous auriez pu manquer facilement, et beaucoup de choses trouvées peuvent entraîner des problèmes (pas tout) –