cocos2d-x iOS SimpleAudioEngine or OpenGL context Crash Error

 언제부터인지 모르겠지만 cocos2d-x로 개발중 iOS Device에서 게임 실행중에 Home버튼을 눌러 나가기만하면 Crash가 발생했었습니다. 그 위치는...

- (void) swapBuffers
{
...
...
     if(![context_ presentRenderbuffer:GL_RENDERBUFFER])
...
}

 바로 EAGLView.mm의 저 if문쪽에서 딱 걸리더군요. 이거 뭐지? 이러면서 그동안 작업했던 Framework Static Lib에 메모리라도 잘 못 건들고 있나 싶었죠. Clean Build 해도 해결되지 않았습니다.

 안되겠다 싶어서 Framework개발한 것 하나하나 사용 안하게 주석으로 막고 사용해보다가 마지막에 엉뚱하게도 SimpleAudioEngine::sharedEngine()을 사용한 부분을 주석달고 해보니 잘 되는게 아니겠습니까!? 몇차례 Framework부분과 SimpleAudioEngine::sharedEngine()부분을 주석했다 풀었다를 더 해봤지만 역시나 SimpleAudioEngine::sharedEngine()쪽이 문제의 원인이더군요. 이상하죠? 여태 잘 되던 사운드가 왜 갑짜기 이 난리통인지?

 그려러니 하고 다른 기능 개발중 증상이 심해졌습니다. Home버튼 누르기도 전인 SimpleAudioEngine::sharedEngine()->playBackgroundMusic() 등으로 Sound 재생만 하면 App이 멈추더군요. 지금은 에러가 수정 된 후라 정확히 기억은 안나지만 로우레벨딴인 openAL쪽이었던 것으로 기억나네요.

 증상은 점점 심해지고 제가 만든 Framework 때문인가? 걱정을 살짝 하면서 cocos2d-x Tests 프로젝트에서 CocosDenshionTest을 실행해봤습니다. 왠걸... CocosDenshionTest 버튼을 클릭하자마자 먹통이 되더군요. 일단 제가 Framework 문제는 아니라는 것에 안도의 한숨 한번 날리고~ Xcode Log를 봤습니다. 좀 길어요.

AudioStreamBasicDescription:  2 ch,  44100 Hz, 'lpcm' (0x00000C2C) 8.24-bit little-endian signed integer, deinterleaved
2012-11-06 14:11:55.465 tests[5019:10a03] Error loading /System/Library/Extensions/AudioIPCDriver.kext/Contents/Resources/AudioIPCPlugIn.bundle/Contents/MacOS/AudioIPCPlugIn:  dlopen(/System/Library/Extensions/AudioIPCDriver.kext/Contents/Resources/AudioIPCPlugIn.bundle/Contents/MacOS/AudioIPCPlugIn, 262): Symbol not found: ___CFObjCIsCollectable
  Referenced from: /System/Library/Frameworks/Security.framework/Versions/A/Security
  Expected in: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
 in /System/Library/Frameworks/Security.framework/Versions/A/Security
2012-11-06 14:11:55.501 tests[5019:10a03] Error loading /System/Library/Extensions/AppleHDA.kext/Contents/PlugIns/AppleHDAHALPlugIn.bundle/Contents/MacOS/AppleHDAHALPlugIn:  dlopen(/System/Library/Extensions/AppleHDA.kext/Contents/PlugIns/AppleHDAHALPlugIn.bundle/Contents/MacOS/AppleHDAHALPlugIn, 262): Symbol not found: ___CFObjCIsCollectable
  Referenced from: /System/Library/Frameworks/Security.framework/Versions/A/Security
  Expected in: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
 in /System/Library/Frameworks/Security.framework/Versions/A/Security
2012-11-06 14:11:55.520 tests[5019:10a03] Error loading /System/Library/Extensions/AppleHDA.kext/Contents/PlugIns/AppleHDAHALPlugIn.bundle/Contents/MacOS/AppleHDAHALPlugIn:  dlopen(/System/Library/Extensions/AppleHDA.kext/Contents/PlugIns/AppleHDAHALPlugIn.bundle/Contents/MacOS/AppleHDAHALPlugIn, 262): Symbol not found: ___CFObjCIsCollectable
  Referenced from: /System/Library/Frameworks/Security.framework/Versions/A/Security
  Expected in: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
 in /System/Library/Frameworks/Security.framework/Versions/A/Security

 보면 Audio 관련된 것들이 loading에러가 났다고 합니다. 구글링을 해보니 iOS SDK 5.0의 버그로 Simulator에서만 나는 무시해도 되는 로그일 뿐이라는군요. Xcode 4.5, iOS SDK 6.0에서는 해결이 된 모양입니다. 뭐 암튼 로그는 로그일 뿐, Home 버튼 후 다시 실행시 Crash와 Sound 파일 로딩부터 Crash나는 것은 어쩔껀데? ㅜ.ㅜ

 순간! Mac OSX 시스템 볼륨을 0 으로 했던 것이 생각나더군요. 에이 설마..... 볼륨을 올리고 깔끔하게 재부팅 후 CocosDenshionTest 실행 잘됨. Framework를 포함한 Test Game역시 아무문제 없이 잘 됨. 이거뭐지? 볼륨 0으로 하고 다시 재부팅후 해도 잘됨...대체 뭐지?

 기쁨도 잠시뿐.. 역시 저절로 해결되는 버그는 제대로 해결되지 않는 것인가 보네요. 다시 또 에러가 발생합니다. 이제는 다른 팀원도 발생하네요 ㅜ.ㅜ...

http://www.cocos2d-x.org/boards/6/topics/10985
http://www.cocos2d-x.org/boards/6/topics/10988?r=10999#message-10999
http://www.cocos2d-iphone.org/forum/topic/7163
http://www.cocos2d-iphone.org/forum/topic/7326

 좀더 구글링을 통해 해결법을 찾았습니다. iOS가 멀티태스킹이 되면서 생긴 버그인듯 보이네요. 링크를 보면 그래픽쪽 이슈인데 사운드와 관련이 있다 없다의 토론으로 의견이 분분한데 아무튼 위와 같은 증상과 함께

sgx error (background gpu access not permitted):
Program received signal: “SIGABRT”.

 이같은 로그도 나오거나 Home 버튼을 눌러 멀티태스킹 중 앱이 죽는다면 아래와 같이 해결하면 됩니다.

void AppDelegate::applicationDidEnterBackground()
{
//    CCDirector::sharedDirector()->pause();
        CCDirector::sharedDirector()->stopAnimation();
...
}

void AppDelegate::applicationWillEnterForeground()
{
//    CCDirector::sharedDirector()->resume();
    CCDirector::sharedDirector()->startAnimation();
...
}

 기존에 pause와 resume대신 stopAnimation과 StartAnimation으로 대체합니다. 소스를 따라가보면 - (void) swapBuffers는 

void CCDisplayLinkDirector::mainLoop(void)
{
    if (m_bPurgeDirecotorInNextLoop)
    {
        m_bPurgeDirecotorInNextLoop = false;
        purgeDirector();
    }
    else if (! m_bInvalid)
     {
         drawScene();
...
}

 CCDirector의 mainLoop에서 m_bInvalid가 false일 때 drawScene()를 통해 내부적으로 호출이 되죠. 근데 pause나 resume으로는 m_bInvalid에 아무 영향을 주지 않습니다. stopAnimation과 startAnimation이 영향을주죠.

 여기서 웃긴건 지금 2.0.1을 쓰는 중인데 샘플로 있는 tests 프로젝트에는

void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();
    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
    SimpleAudioEngine::sharedEngine()->pauseAllEffects();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->startAnimation();
    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
    SimpleAudioEngine::sharedEngine()->resumeAllEffects();
}

 이미 이렇게 stopAnimation과 startAnimation으로 하고 있네요. xcode template로 자동 생성한 프로젝트는 왜 pause와 resume으로 하는것이냐!!

댓글

이 블로그의 인기 게시물

'xxx.exe' 프로그램을 시작할 수 없습니다. 지정된 파일을 찾을 수 없습니다.

goorm IDE에서 node.js 프로젝트로 Hello World Simple Server 만들어 띄워보기

애드센스 수익을 웨스턴 유니온으로 수표대신 현금으로 지급 받아보자.