8

I have a 100% reproducible crash here.

Crash if backgrounding cocos2d 2.1 app in iOS7 while watching Game Center screens (leaderboard, achievement). It crashes instantly when pushing the home button.

Crash on line 275 in CCGLView.m:

if(![_context presentRenderbuffer:GL_RENDERBUFFER])

The itching thing is, I downloaded a fresh copy of official cocos2diphone 2.1 the other second, installed its templates and ran the staple application after hooking it up to the same app id as my problematic app that already have game center leaderboards etc set up. It does not crash. So I ran a diff on the cocos2d folders inside lib, and there is no difference except I added some C functions code in CCDrawingPrimitives.h/m... Should not be the problem. So the problem should not be in cocos2d itself but somehow the use of it or my project setup causes it.

Update:

The problem seems to be in the cocos2d app template in use in 2.1 and possibly earlier. It looks like this:

-(void) applicationDidEnterBackground:(UIApplication*)application
{
    if( [navController_ visibleViewController] == director_ )
        [director_ stopAnimation];
}

And the obvious fault here is that if you have navController open a Game Center controller, then when pushing the home button the visibleViewController of director_ will be the GC controller, hence the stopAnimation will not get called. This results in a crash with iOS7, but doesn't seem to with iOS6... nor the template cocos2d 2.1 app (still confused here).

The current fix is to comment out if( [navController_ visibleViewController] == director_ ) in order to have stopAnimation always called. Not sure if there are any side effects with that but will go with this for now.

Jonny
  • 15,955
  • 18
  • 111
  • 232
  • 1
    in the past week, that line of code has been associated (in this forum) with a number of oddballs : crash, leak, random sprite appearing out of the blue. For my part, just running the release version nukes the leak (substantial). Seems to be some issue with iOS7/debug as far as i could determine, and (possibly but not certain) that line. – YvesLeBorg Oct 10 '13 at 02:00
  • So how come it does not crash on a fresh 2.1? Also, I have a live cocos2d game out there using the same class I use for dealing with scores and game center. It crashes the same way when backgrounding while in a game center view. It's certainly not debug mode. Try it if you like ( https://itunes.apple.com/jp/app/chitchaiossan-pyonpyon/id667884819?mt=8 ) On another possibly unrelated note I noticed that iOS7 once again changed how GC controllers should be displayed http://stackoverflow.com/a/19143224/129202 having a hard time keeping up with all versions here :-P – Jonny Oct 10 '13 at 02:11
  • Well, believe it or not : in my case, i have 2 IDE's (i only use xCode to play certificates and prep for release). So, same code base, run with AppCode : no leak. Run with xCode : massive leak on that line. Run with AppCode, but attach Instruments to a running process : leak. I was completely baffled by this thing. So dont be surprised : there is something broken (i think) in the buildForDebuggUnderIOS7 process within xcode. – YvesLeBorg Oct 10 '13 at 02:23
  • There is more. When checking crash reports for above mentioned live app in iTunes Connect, I have a crash log detailing the very same line , but for iOS 6.1. **OS Version: iOS 6.1.4 (10B350) Crashed Thread: 0 4 OpenGLES 0x34359df0 -[EAGLContext presentRenderbuffer:] + 72 5 ossan 0x000aa498 -[CCGLView swapBuffers] (CCGLView.m:275)** – Jonny Oct 10 '13 at 03:17
  • 2
    Any OpenGL usage must stop the moment an app enters background. So for whatever reason cocos2d isn't properly suspended. Check app delegate specifically resign active and enter background messages, both should have code that stops the director from animating. – CodeSmile Oct 10 '13 at 05:11
  • Ok the reason might be this staple code in appcontroller: `-(void) applicationDidEnterBackground:(UIApplication*)application { if( [navController_ visibleViewController] == director_ ) [director_ stopAnimation]; }` Of course if Game center (or something like a SKStore controller or whatever) is visible in navController, then director_ would not be stopped and maybe iOS7 is less lenient than previous iOS about it and has the app crash... – Jonny Oct 10 '13 at 05:32
  • I commented out the first line `if( [navController_ visibleViewController] == director_ )` and it seems to fix the crash problem. Wonder about the reason for that one anyway. Will have to try this fix out for any side effects for awhile. – Jonny Oct 10 '13 at 05:41
  • Another solution is to use `stopAnimation` when showing a Game Center view controller (that's what I'm doing and it seems to work so far). Perhaps this is the intended reason for the template code in the app delegate? You `stopAnimation` when `CCDirector` stops being active - either because the app got backgrounded or because it is not the active view controller any more. – baris Dec 04 '13 at 19:18
  • I got a crash on this line again yesterday after adding a 3rd party SDK that opens a UIKit-ish view controller on top of everything - and backgrounding the app. `stopAnimation` did NOT help. I had to make sure that the 3rd party view controller was dismissed immediately (no animations) when the app would go into background mode. – Jonny Dec 17 '13 at 06:27

1 Answers1

4

Good Call. I ran into the same issue as you do and your post helped me to figure out how my app crashed.

So my solution is stop director animation before showing game center.

[[CCDirector sharedDirector] stopAnimation]
[[CCDirector sharedDirector] presentViewController:gcViewController animated:YES completion:nil];

Then restart animation in the game center view dismiss callback

- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController
{
    [[CCDirector sharedDirector] dismissViewControllerAnimated:YES completion:nil];
    [[CCDirector sharedDirector] startAnimation];
}

Your updated solution should work, but same here, I am not sure if there would be any side effects. I guess it is a safer approach to just wrap around the game center itself.

Thanks again for posting this question!

zeroliu
  • 990
  • 2
  • 10
  • 15
  • There might be other screens that would cause the same issue, like App store screens, and possibly other in the future. – Jonny Mar 27 '14 at 03:57