Sous Xcode 3.x et iOS 4, si une exception non gérée est signalée dans l'émulateur, une trace de pile d'exceptions (similaire à Java) est produite dans la sortie de la console.
Lorsque je déclenche une exception non gérée dans iOS 5 sous Xcode 4.2, en exécutant exactement le même code d'application, la trace de la pile ne se produit pas. (J'ai compris comment définir un point d'arrêt d'exception, mais cela ne produit pas de traceback dans la console.)
S'agit-il simplement d'un paramètre Xcode que je dois définir quelque part, ou d'une "fonctionnalité" de Xcode 4/iOS 5? Existe-t-il un moyen de restaurer ce morceau de fonctionnalité?
Malheureusement, l'ajout d'un uncaughtExceptionHandler
ne fonctionne pas. Voici le gestionnaire:
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"uncaughtExceptionHnadler -- Exception %@", [exception description]);
// Because iOS 5 doesn't provide a traceback, provide one here
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
// Let Flurry look at the error
[FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}
(Il s'avère qu'il était déjà présent, pour faire le truc Flurry, alors j'ai juste ajouté la trace de la pile.)
Voici où il est activé (juste quelques lignes ci-dessous où le gestionnaire est déclaré):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Enable uncaught exception handler to dump stack and let Flurry log the exception
NSUncaughtExceptionHandler* hdlr = NSGetUncaughtExceptionHandler();
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
NSUncaughtExceptionHandler* newHdlr = NSGetUncaughtExceptionHandler();
// TODO: Test
NSException* ex = [NSException exceptionWithName:@"AssertionFailure" reason:@"Test" userInfo:nil];
@throw ex;
J'ai défini des points d'arrêt pour me permettre de vérifier les deux valeurs de gestionnaire récupérées. La première est nulle et la seconde est une adresse apparemment valide. Mais lorsque l'exception de test est levée, le gestionnaire (dans le simulateur iOS 5) ne prend jamais le contrôle. (Bien que lorsque je lance sur le simulateur iOS 4.2, il prend le contrôle.)
La définition de NSExceptionHandlingMask
n'est apparemment pas possible sur iPhone. Le prérequis ExceptionHandling.framework
n'est pas disponible.
Cela marche:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
[pool release];
return retVal;
}
Cela marche:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
[pool release];
return retVal;
}
Pour ARC:
int main(int argc, char *argv[]) {
int retVal = -1;
@autoreleasepool {
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
}
return retVal;
}
Toujours en attente d'une sorte d'explication pour expliquer pourquoi le vidage par défaut ne fonctionne plus et/ou pourquoi (encore plus grave) uncaughtExceptionHandler ne fonctionne pas. Cependant, apparemment, ce problème affecte uniquement l'émulateur.
Il a été souligné que si vous allez dans Product -> Scheme -> Edit Scheme, sélectionnez "Run (Debug)", sélectionnez l'onglet "Diagnostics" et cliquez sur "Log Exceptions", cela restaurera la journalisation des exceptions par défaut Xcode manquante , peut-être (je ne l'ai pas encore essayé) éliminant la nécessité du hack ci-dessus.
C'est un problème connu ... pour des solutions de contournement voir ici et ici .
Une autre option pourrait consister à
defaults write NSGlobalDomain NSExceptionHandlingMask 63
Bien que ce soit généralement pour OSX, cela peut aider lors de l'utilisation de l'émulateur - je ne peux pas l'essayer pour l'instant :-(
J'ai eu le même problème, réactiver "Compile for Thumb" a fonctionné pour moi. Remarque: Je ne l'ai réactivé que pour la configuration de débogage, pour des raisons évidentes.