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

キャッチされていない例外です。スローされた例外を説明するログメッセージが表示されるはずです。


ええと....醜い...それはクラッシュを引き起こす不正な形式の例外です。

おそらく、アプリが何らかの形でメモリを破壊しています。例外ブレークポイントを作成し(デバッガーUIにあります)、デバッガーでブレークポイントを取得できるかどうかを確認します。これはバックトレースのrethrow()であるため、元のthrowが実際に役立つ場合があります。

于 2013-03-22T16:42:13.967 に答える
0

私も、DisplayLinkのハンドラーでNSExceptionを発生させた結果であるこのスタックトレースでEXC_BAD_ACCESSを確認しています。例えば:

#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 ()

この再現は、Xcode4.6.2のOpenGLゲームアプリケーションテンプレートの-[ViewControllerglkView:drawInRect:]関数で例外を発生させることによって作成されました。

興味深いことに、iOS 6.0以降を実行しているデバイスとシミュレータの両方で再現されますが、iOS5.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

この自動リリースプールは、iOS6.0で導入されたようです。

考えられる回避策:CADisplayLinkターゲット関数ですべてのNSExceptionをキャッチし、それらを手動で保持して再スローするか、未処理の例外ハンドラーを呼び出してから中止します。

于 2013-05-01T00:08:25.337 に答える