CCLabelBMFont segfaults on app startup

Hey all,

I realize this could potentially be an issue with the JS bindings layer, but posted in the C++ framework since that’s where the error is being thrown.

I’m seeing an assert thrown almost immediately on startup of our iOS and Android apps. It occurs about 9/10 times on Android and about 1/10 times on iOS. The error looks something like this:

04-02 21:10:16.000: E/cocos2d-x assert(25535): /cocos2dx/cocoa/CCObject.cpp function:release line:82
04-02 21:10:16.000: A/libc(25535): Fatal signal 11 (SIGSEGV) at 0x00740075 (code=1)

Some more information from the stack trace…

04-02 21:10:16.905: I/DEBUG(21889):          #00  pc 0016a490  /path/to/game.so (_ZN7cocos2d8CCObject7releaseEv)
04-02 21:10:16.905: I/DEBUG(21889):          #01  pc 0018f814  /path/to/game.so (_ZN7cocos2d17CCSpriteBatchNodeD1Ev)
04-02 21:10:16.905: I/DEBUG(21889):          #02  pc 001740b6  /path/to/game.so (_ZN7cocos2d13CCLabelBMFontD1Ev)
04-02 21:10:16.905: I/DEBUG(21889):          #03  pc 001740c8  /path/to/game.so (_ZN7cocos2d13CCLabelBMFontD0Ev)
04-02 21:10:16.905: I/DEBUG(21889):          #04  pc 0016a4d0  /path/to/game.so (_ZN7cocos2d8CCObject7releaseEv)
04-02 21:10:16.905: I/DEBUG(21889):          #05  pc 0019383c  /path/to/game.so (_ZN7cocos2d23ccArrayRemoveAllObjectsEPNS_8_ccArrayE)
04-02 21:10:16.905: I/DEBUG(21889):          #06  pc 0016830a  /path/to/game.so (_ZN7cocos2d13CCPoolManager3popEv)
04-02 21:10:16.905: I/DEBUG(21889):          #07  pc 0018ad82  /path/to/game.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender)
04-02 21:10:16.910: I/DEBUG(21889):          #08  pc 0001ecf0  /system/lib/libdvm.so (dvmPlatformInvoke)
04-02 21:10:16.910: I/DEBUG(21889):          #09  pc 00058fac  /system/lib/libdvm.so (_Z16dvmCallJNIMethodPKjP6JValuePK6MethodP6Thread)

The assert is being thrown due to the object being released more than once. I’m assuming this is happening due to the autorelease code, but I’m not sure. The error appears to happen when I’m adding methods to the cc.LabelBMFont.prototype in JS. Just adding the methods makes it get called. If I comment out all places where we use this, it runs fine. If we add 1 prototype method in JS, it segfaults every time.

I’m not quite sure how to debug this, but if anyone has any tips, I’d love to find out more.

Thanks,

— Joel

Some more info on this:

I commented out the CCAssert and changed the release method in CCObject.cpp to look like this:

void CCObject::release(void)
{
    // CCAssert(m_uReference > 0, "reference count should greater than 0");
    if(m_uReference > 0) {
        --m_uReference;

        if (m_uReference == 0)
        {
            delete this;
        }
    }
}

I’m still receiving the same error. Is it possible that there’s memory corruption going on?

Thanks,

— Joel

I wound up digging further into this and found the cause and a solution.

The Cause:

We extended cc.LabelBMFont in the JS code. The extend function will create an instance of the class, but will never call init on that instance.

For CCLabelBMFont and CCSpriteBatchNode, a couple of variables are not initialized to null, and calling the destructor without calling the init function will result in the above error.

The Solution:

in CCSpriteBatchNode, we added a constructor:

CCSpriteBatchNode::CCSpriteBatchNode()
: m_pobTextureAtlas(NULL)
, m_pobDescendants(NULL)
{
}

in CCLabelBMFont, we changed the constructor by adding a line to the variable settings:

, m_pReusedChar(NULL)

This seems like a good candidate for a patch - I don’t see any way this could break existing functionality.