3

我在 Xcode 制作的 iOS 游戏中遇到 EXC_BAD_ACCESS 异常。它发生在模拟器和真实设备上。它总是在游戏中的同一部分,但并不总是发生。它很神秘,因为它似乎与游戏的对象没有任何关系,只是与默认的库/系统方法有关。Xcode 也没有显示是哪一行代码导致了它(但它显示了汇编中的哪一行)。我在下面发布回溯。可能是什么原因造成的?我怎样才能找出问题所在?

thread #1: tid = 0x1c03, 0x01980051 libobjc.A.dylib`_cache_getImp + 9, stop reason = EXC_BAD_ACCESS (code=1, address=0xc0000008)
frame #0: 0x01980051 libobjc.A.dylib`_cache_getImp + 9
frame #1: 0x0196dac4 libobjc.A.dylib`lookUpMethod + 42
frame #2: 0x0196da88 libobjc.A.dylib`class_respondsToSelector + 65
frame #3: 0x023160d3 CoreFoundation`objectIsKindOfClass + 51
frame #4: 0x0239f087 CoreFoundation`__handleUncaughtException + 71
frame #5: 0x0196f0b9 libobjc.A.dylib`_objc_terminate() + 86
frame #6: 0x01da2a65 libc++abi.dylib`safe_handler_caller(void (*)()) + 13
frame #7: 0x01da2acd libc++abi.dylib`std::terminate() + 23
frame #8: 0x01da3c4e libc++abi.dylib`__cxa_rethrow + 83
frame #9: 0x0196efbd libobjc.A.dylib`objc_exception_rethrow + 47
frame #10: 0x022bbf98 CoreFoundation`CFRunLoopRunSpecific + 360
frame #11: 0x022bbe1b CoreFoundation`CFRunLoopRunInMode + 123
frame #12: 0x01df57e3 GraphicsServices`GSEventRunModal + 88
frame #13: 0x01df5668 GraphicsServices`GSEventRun + 104
frame #14: 0x00aa5ffc UIKit`UIApplicationMain + 1211
frame #15: 0x000026e1 Game`main(argc=1, argv=0xbffff3bc) + 95 at main.m:6
frame #16: 0x00002645 Game`start + 53
4

2 回答 2

3

这是一个未被发现的例外。应该有一条日志消息描述所引发的异常。


Ew....丑陋...这是导致崩溃的格式错误的异常。

很可能,您的应用程序正在以某种方式破坏内存。创建一个异常断点(它在调试器 UI 中)并查看是否可以让它在调试器中中断。由于它是回溯中的 rethrow(),因此原始 throw 实际上可能很有用。

于 2013-03-22T16:42:13.967 回答
0

我也看到了带有此堆栈跟踪的 EXC_BAD_ACCESS,这是在 DisplayLink 的处理程序中引发 NSException 的结果。例如:

#0  0x01142e52 in objc_exception_throw ()
#1  0x01d04deb in +[NSException raise:format:] ()
#2  0x00005502 in -[ViewController glkView:drawInRect:] at ViewController.m:225
#3  0x010e8675 in -[GLKView _display:] ()
#4  0x010e8c89 in -[GLKView display] ()
#5  0x010e9ab7 in -[GLKViewController _updateAndDraw] ()
#6  0x01156663 in -[NSObject performSelector:] ()
#7  0x010e900f in -[GLKDisplayLinkMessenger message] ()
#8  0x0231f2d2 in CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long) ()
#9  0x0231f75f in CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) ()
#10 0x01cc4376 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#11 0x01cc3e06 in __CFRunLoopDoTimer ()
#12 0x01caba82 in __CFRunLoopRun ()
#13 0x01caaf44 in CFRunLoopRunSpecific () 
#14 0x01caae1b in CFRunLoopRunInMode ()
#15 0x01c5f7e3 in GSEventRunModal ()
#16 0x01c5f668 in GSEventRun ()
#17 0x0001a65c in UIApplicationMain ()

此重现是通过在 Xcode 4.6.2 中的 OpenGL 游戏应用程序模板的 -[ViewController glkView:drawInRect:] 函数中引发异常而产生的。

有趣的是,它可以在运行 iOS 6.0+ 的设备和模拟器上重现,但不能在 iOS 5.1 上重现。

在四处寻找之后,似乎在 iOS 6.0+ 中,向 DisplayLink::Dispatch 添加了一个自动释放池,并且它似乎在未处理的异常处理程序有机会之前对 NSException 进行了分配:

#0     0x01d07470 in -[NSException dealloc] ()
#1     0x011569ff in -[NSObject release] ()
#2     0x011550d5 in objc_release ()
#3     0x01155bd9 in (anonymous namespace)::AutoreleasePoolPage::pop(void*) ()
#4     0x01ca7468 in _CFAutoreleasePoolPop ()
#5     0x0230ffc1 in CA::AutoreleasePool::~AutoreleasePool() ()
#6     0x0231f3d2 in CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long  long) ()
#7     0x0231f75f in CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) ()
#8     0x01cc4376 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#9     0x01cc3e06 in __CFRunLoopDoTimer ()
#10     0x01caba82 in __CFRunLoopRun ()
#11     0x01caaf44 in CFRunLoopRunSpecific ()
#12     0x01caae1b in CFRunLoopRunInMode ()
#13     0x01c5f7e3 in GSEventRunModal ()
#14     0x01c5f668 in GSEventRun ()
#15     0x0001a65c in UIApplicationMain ()
#16     0x00002c3d in main

这个自动释放池似乎在 iOS 6.0 中就位。

可能的解决方法:在 CADisplayLink 目标函数中捕获所有 NSException,然后手动保留它们并重新抛出,或者调用未处理的异常处理程序,然后中止。

于 2013-05-01T00:08:25.337 回答