Xcode 4.2/iOS 5 下控制台中没有异常堆栈跟踪?

Posted

技术标签:

【中文标题】Xcode 4.2/iOS 5 下控制台中没有异常堆栈跟踪?【英文标题】:No exception stacktrace in console under Xcode 4.2/iOS 5? 【发布时间】:2011-12-27 08:31:23 【问题描述】:

在 Xcode 3.x 和 ios 4 下,如果在模拟器中发出未处理的异常信号,则会在控制台输出中生成异常堆栈跟踪(类似于 Java 的)。

当我在 Xcode 4.2 下的 iOS 5 中引发未处理的异常时,运行完全相同的应用程序代码,堆栈跟踪不会发生。 (我确实想出了如何设置异常断点,但这不会在控制台中产生回溯。)

这仅仅是我需要在某处进行的 Xcode 设置,还是 Xcode 4/iOS 5 的“功能”?有没有办法恢复这部分功能?

更新

很遗憾,添加 uncaughtExceptionHandler 不起作用。这是处理程序:

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];
                                               

(事实证明它已经存在,为了做 Flurry 的事情,所以我只是添加了堆栈跟踪。)

这里是启用它的地方(就在声明处理程序的下面几行):

- (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; 

我设置了断点以使我能够检查两个检索到的处理程序值。第一个是 nil,第二个是明显有效的地址。但是当测试异常被抛出时,处理程序(在 iOS 5 模拟器中)永远不会得到控制。 (虽然当我在 iOS 4.2 模拟器上运行时,它确实得到了控制。)

在 iPhone 上设置 NSExceptionHandlingMask 显然是不可能的。先决条件ExceptionHandling.framework 不可用。

更新 2

这行得通:

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;

【问题讨论】:

酷,很高兴它已解决 :-) 也许您可以将其添加为答案(不仅仅是在问题正文中)。 我可以,如果没有其他人想出使 uncaughtExceptionHandler 工作的修复程序。 仍在等待有关为什么默认转储不再起作用和/或为什么(更严重)uncaughtExceptionHandler 不起作用的某种解释。 您描述的问题似乎只影响模拟器...在真实设备上它应该可以正常工作... 很高兴您将其他问题(询问不同的事情)标记为重复问题,以此作为回溯该问题的借口,这样您的问题将获得更多可见性,从而为您获得更多分数。恭喜您弄清楚如何玩弄系统,但结果,您得到了我的问题 - 尚未得到回答 - 作为一个骗子关闭,这使得 *** 对每个人都没有用处。 【参考方案1】:

这行得通:

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;

对于 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;

仍在等待有关为什么默认转储不再起作用和/或为什么(甚至更严重)uncaughtExceptionHandler 不起作用的某种解释。但是,显然这个问题只影响模拟器。

更新:

已经指出,如果你去Product -> Scheme -> Edit Scheme,选择“Run(Debug)”,选择“Diagnostics”选项卡,然后点击“Log Exceptions”,这样会恢复丢失的Xcode默认异常日志记录,可能(我还没有尝试过)消除了对上述 hack 的需要。

【讨论】:

如果您使用 ARC,只需将 autorelease alloc/release 更改为 @autoreleasepool ... 可能只是忘记了,但为了返回值retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([YourAppDelegate class]));,我不得不这样做 这根本不需要。你只需要创建异常断点,见blog.manbolo.com/2012/01/23/xcode-tips-1-break-on-exceptions 仅仅启用“僵尸对象”就让我摆脱了困扰我一整天的问题! 这真的是一个巨大的帮助!让我真正找到了问题所在。谢谢@HotLicks【参考方案2】:

这是一个已知问题...有关解决方法,请参阅 here 和 here。

另一个选择可能是

defaults write NSGlobalDomain NSExceptionHandlingMask 63

虽然它通常适用于 OSX,但在使用模拟器时可能会有所帮助 - 不过我现在无法尝试 :-(

【讨论】:

fwiw defaults write NSGlobalDomain NSExceptionHandlingMask 63 对我不起作用。 另外,这不适用于 iOS SDK。【参考方案3】:

我遇到了同样的问题,重新打开“Compile for Thumb”对我有用。注意:出于明显的原因,我只为调试配置重新打开它。

【讨论】:

以上是关于Xcode 4.2/iOS 5 下控制台中没有异常堆栈跟踪?的主要内容,如果未能解决你的问题,请参考以下文章

iTunes 同步中的未知错误 0xE8003FFE(Xcode 4.2、iOS SDK 5.0、iPod 第二代 iOS 4.2.1)

Xcode 4.2 iOS 空应用程序和故事板

Xcode 5 不打印异常详细信息

Xcode 4.2 + iOS6 = Interface Builder 错误

Xcode 4.2 iOS程序如何给按钮等添加点击后的代码

Xcode 4.5 黑屏或异常:“一个视图一次只能与一个视图控制器关联!”