系统库中iOS上的EXC_BAD_ACCESS

时间:2013-03-22 16:36:22

标签: ios objective-c xcode exception exc-bad-access

我在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

2 个答案:

答案 0 :(得分:3)

这是一个未被捕获的例外。应该有一条日志消息描述抛出的异常。


......丑......这是一个导致崩溃的畸形异常。

很可能,你的应用程序在某种程度上破坏了内存。创建一个异常断点(它位于调试器UI中)并查看是否可以在调试器中使其中断。由于它是回溯中的rethrow(),原始抛出实际上可能是有用的。

答案 1 :(得分: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 ()

这个repro是通过在Xcode 4.6.2中的OpenGL Game应用程序模板的 - [ViewController glkView:drawInRect:]函数中引发异常而产生的。

有趣的是,它在运行iOS 6.0+的设备和模拟器上进行了重新编译,但在iOS 5.1上却没有。

在浏览之后,似乎在iOS 6.0+中,一个自动释放池被添加到DisplayLink :: Dispatch中,并且它似乎是在未处理的异常处理程序获得机会之前对NSException进行dalloc:

#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目标函数中的所有NSExceptions,然后手动保留它们并重新抛出,或者调用未处理的异常处理程序,然后中止。