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,但在使用模拟器时可能会有所帮助 - 不过我现在无法尝试 :-(
【讨论】:
fwiwdefaults 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)