¿No hay seguimiento de pila de excepción en la consola en Xcode 4.2/iOS 5?
En Xcode 3.x y iOS 4, si se señala una excepción no controlada en el emulador, se produce un seguimiento de la pila de excepción (similar al de Java) en la salida de la consola.
Cuando genero una excepción no controlada en iOS 5 en Xcode 4.2, ejecutando exactamente el mismo código de aplicación, no se produce el seguimiento de la pila. (Descubrí cómo establecer un punto de interrupción de excepción, pero eso no produce el rastreo en la consola).
¿Es esto simplemente una configuración de Xcode que necesito realizar en alguna parte, o una "característica" de Xcode 4/iOS 5? ¿Hay alguna manera de restaurar esta funcionalidad?
Actualizar
Desafortunadamente, agregar un uncaughtExceptionHandler
no funciona. Aquí está el controlador:
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];
}
(Resulta que ya estaba presente para hacer lo de Flurry, así que simplemente agregué el seguimiento de la pila).
Aquí es donde está habilitado (solo unas pocas líneas debajo donde se declara el controlador):
- (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;
Establecí puntos de interrupción para permitirme verificar los dos valores del controlador recuperados. El primero es nulo y el segundo es una dirección aparentemente válida. Pero cuando se lanza la excepción de prueba, el controlador (en el simulador de iOS 5) nunca obtiene el control. (Aunque cuando ejecuto el simulador de iOS 4.2, obtiene el control).
Aparentemente, la configuración NSExceptionHandlingMask
no es posible en iPhone. El requisito previo ExceptionHandling.framework
no está disponible.
Actualización 2
Esto funciona:
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;
}
Esto funciona:
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;
}
Para ARCO:
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;
}
Todavía estoy esperando algún tipo de explicación de por qué el volcado predeterminado ya no funciona y/o por qué (aún más grave) uncaughtExceptionHandler no funciona. Sin embargo, al parecer este problema sólo afecta al emulador.
actualizar:
Se ha señalado que si va a Producto -> Esquema -> Editar esquema, selecciona "Ejecutar (depurar)", selecciona la pestaña "Diagnóstico" y hace clic en "Registrar excepciones", esto restaurará el registro de excepciones predeterminado de Xcode que falta. , posiblemente (aún no lo he probado) eliminando la necesidad del truco anterior.
Este es un problema conocido... para soluciones alternativas, consulte aquí y aquí .
Otra opción podría ser
defaults write NSGlobalDomain NSExceptionHandlingMask 63
Aunque normalmente es para OSX, puede resultar útil al utilizar el emulador. Aunque no puedo probarlo ahora :-(