EXC_BAD_ACCESS in update function after scene restart

I’ve been wrestling with this issue for weeks now and I just can’t get it solved, it’s time to swallow my pride and see if a fresh set of eyes can help me out.

Basically I created my game first in HTML5 and now and attempting to use JSB to build for iOS, and everything is working PERFECTLY (very impressive). The only issue that I can’t seem to figure out is after you die in my game I give the option to restart, which essentially calls:
cc.Director.getInstance().replaceScene(cc.TransitionFade.create(0.6, GamePlayLayerScene.create()));
where GamePlayLayerScene.create() is:

GamePlayLayerScene = cc.Scene.extend({
    onEnter:function () {
    
        this._super();
        var layer = new GamePlayLayer();
        layer.init();
        this.addChild(layer);
    
    }
});

GamePlayLayerScene.create = function() {

    return new GamePlayLayerScene();

};

For some reason, it doesn’t matter what I do, after restarting the game I get the error shown in my attached screenshot during the update function. I cannot figure out what to do, where I’m totally lost is why it would work the first time through and then crash the second! Is this a bug in the JSB? Am I crazy?


Screen Shot 2014-03-20 at 12.10.22 PM.png (345.7 KB)

Hi,

I think it’s related to JSB’s garbage collection, there must be some node which have been released while you restart the scene for the second time. You should find this node via the call stack when the issue occurred, and then make a retain to it:

node.retain();

But I can’t tell where exactly you can find it because it’s related to your game logic and structure.

Huabin

Huabin,

Thanks so much for taking the time to help me with this issue, I really appreciate it.

What I’m confused about is generally I’ve found that when the problem is a node that has been released prematurely I get the Error: Invalid Native Object error. Also I wouldn’t have thought any nodes would be retained at all through a scene replacement, am I wrong?

Thanks again!

You are welcome!:wink:

EXC_BAD_ACCESS can happen also, if an node get released then the pointer pointed to it will become a wild pointer which will cause the error while you use it.

Can you capture the full call stack to show us what’s happening while the error occurred ?

Let me know if the attached image is verbose enough.

I can only tell that the problem is from schedule functions, can you check all schedule function calls in your Scene, like: schedule, scheduleOnce, scheduleUpdate, etc… And the problem should be the caller of such function have been released.

That could very well be the issue!

I have a few recursive scheduleOnce calls (to make the timing random). I had assumed that these would be unscheduled when the scene was released. Is this not the case? Should I manually unschedule all of these some how?

EDIT::

I added

this.unscheduleAllCallbacks()

to the onExit() method and the crash is still occurring…

I mean, maybe it’s not the schedule call itself, it may be the node who call the schedule functions that have been released.

I’m not sure I follow what you’re saying.

The only node that makes schedule calls is the single layer added to the scene. This layer is definitely being released when the scene is replaced.

Can you paste some code of this layer making schedule calls?

Ok, I’m at a total loss here. I took what Huabin suggested might be the issue (scheduling) and I removed all schedule functions. Now the only thing that happens on a timer is the update function. I removed all elements except the very core of the game, and I’m still getting this issue! I don’t know what to do. Is there any suggestions anyone has to better debug a JSB game in v2.2.2?

@pandamicro I think I might be getting closer. I threw in a manual garbage collection call

__jsc__.garbageCollect();

in the init function of my layer. I can now consistently get EXC_BAD_ACCESS by calling

cc.Director.getInstance().replaceScene(cc.TransitionFade.create(0.6, GamePlayLayerScene.create()));

from within the GamePlayLayerScene 2 times. The first time it works fine, the second time it crashes immediately in the function JSBool ScriptingCore::forceGC(JSContext *cx, uint32_t argc, jsval *vp) on the line JS_GC(rt);.

If anyone has any suggestions on how I could find out what javascript object might be causing this issue I’d be SUPER grateful. Thanks in advanced!

Hi, @treyrich2001

Sorry that I haven’t got time during the weekend, I saw your GamePlayLayer.js, I can’t tell exactly what’s wrong, but I think there are things you can try:

var self = this;
this.scheduleOnce(function() {
    self.addEnemies();
}, 0.1);

You used a lot anonymous functions to schedule call, you don’t need to, just do the following is enough:

this.scheduleOnce(addEnemies, 0.1);

Because schedule is always related to your object, so it’s enough to pass a class function into it.

Huabin

@pandamicro that’s no problem at all. I appreciate you taking the time to respond at all!

The reason for the anonymous functions in the schedule calls is that many of these scheduleOnce calls repeat at random intervals, and schedule once will fail if I try to give it the same callback twice. Regardless of this though I don’t believe that this is the problem because I’ve removed all schedule calls except for this.scheduleUpdate() and am manually handling all schedule logic inside of the update function, and I still am having the issue, so it can’t be the schedule calls causing this problem.

Unfortunately I’m almost to the point where I’ll have to just write this in c++ and maintain two code bases (one for HTML5 and one for Native) as I’m almost 100% certain that this is related in some way to a bug deep in JSB that I don’t have time to figure out how to debug. What’s confusing to me is that other people must be restarting their scenes using JSB, and this problem doesn’t appear to be super wide spread, so why is it happening to me?

Is there any way that I can debug the __jsc__.garbageCollect() call that you know of?

Thanks again for taking the time to help!

I finally got this issue semi figured out, at least to a point that my application doesn’t crash every time you restart the game.

What I needed up doing was a combination of things, first to track down the issue I moved the __jsc__.garbageCollect() call around and realized that if I moved it to after the point that I was initializing this._space = null; (where this._space is my chipmunk space) then the exc_bad_access was thrown in chipmunk code. This led me to believe that the lifespan of chipmunk objects was not what would be expected, so I added code in my onExit function to remove all bodies and shapes from my chipmunk space, then I set the space equal to null. After doing this I was still having issues, which I guessed had to do with the transition between scenes, so I removed the cross-fade from the replace scene call that restarts the game and POOF it works great now!

So it seems that chipmunk spaces aren’t properly released after a scene ends, it also seems that bodies and shapes in the chipmunk scene stick around as well. I’m not sure if this is a bug, or intended behavior, but if it’s intended it needs to be WAY better documented than it currently is, cause I’ve poured more hours than I’m prepared to admit refactoring, and debugging code to finally find this issue.

Also if anyone has any ideas on how I can incorporate that cross-fade back into my game without crashes resulting, I’d be very grateful, but if not I’ll still call this a win.

@treyrich2001

Sorry for not being very helpful the last time.
I’m collecting JSB GC related issues, and we will refactor JSB’s GC process, if you have met other problems or other feedbacks, please let us know