Label render crash

@R101 Update the UI from another thread…?! < winces > I would never do such a horrible thing! But just to be sure, I’ve confirmed that my scheduler works on the main thread.

The code’s more complicated than that, but there you go, a hastily-prepared min working (crashing) example:

Scene’s onEnter:

_timeLabel = cocos2d::Label::createWithTTF("Example label", "fonts/ComicSansMSBold.ttf", 120*ScalingUtils::getScaleForFont());


schedule(CC_SCHEDULE_SELECTOR(SubGameSceneShoot::onSecondElapsed), 1, CC_REPEAT_FOREVER, 0);



void SubGameSceneShoot::onSecondElapsed(float dt){

On button click (which causes a crash):

bool SubGameSceneShoot::onFastForwardButtonClicked()
    auto anotherLabel = cocos2d::Label::createWithTTF("Another example label", "fonts/ComicSansMSBold.ttf", 120*ScalingUtils::getScaleForFont());
    return true;

Misc utils just return a string formatted for the time, nothing special, if I change it to std::to_string(schootGameState.currentTimeSeconds), I also get a crash.

Can you try something out quickly and let me know if it works or not:

bool SubGameSceneShoot::onFastForwardButtonClicked()
        auto* anotherLabel = cocos2d::Label::createWithTTF("Another example label", "fonts/ComicSansMSBold.ttf", 120*ScalingUtils::getScaleForFont());
    }, 0.f, "FastForward");
    return true;

Have you tried to create a minimal sample project that reproduces this issue, just to eliminate any other possible causes of the problem? Also, have you tried it with v3.17.2 of cocos2d-x?

Crashes just as nicely :wink:
Yep, I was thinking of creating the minimal sample project. I’ll try to find time for that. <3 weeks past deadline already>

A clean project with the minimal example does not crash. Dammit! I’ll get back to you when I’ve found the reason. This is intriguing! Thanks for the help :wink: .

That is good to know! Now it’s just a matter of narrowing down the possible causes. Good luck! :wink:

I’m sorry. Bad news. This crash seems a bit random so it got me fooled at first.
Actually, this is a minimal crashing example, on a clean project.

  • at first, it didn’t crash on my iPad mini 4, I had to add and remove some more labels to make it crash.
  • so after a few reinstalls and changes, it started crashing. I then cut the code to the following minimal example, and it still crashes (boo).
  • I installed the app on my iPad Pro to see whether it will crash at once, or later. It crashed after the first install.
  • I ran it on my Huawei tab running Android 8.0. It does not crash, but some of the numbers disappear (!!!).
  • It crashes in the same place as before, in the void Label::updateBatchCommand(Label::BatchCommand &batch) method, line CC_SAFE_RELEASE_NULL(pipelineDescriptor.programState); (doesn’t exactly look like safe releasing, does it? :smiley: )
  • Doesn’t matter whether the font is Marker Felt or ComicSansBold.
    Maybe I’ve done something illegal, using setString like this? Or maybe I should report a bug to the engine guys (how do I do that?)?
bool HelloWorld::init()
    if ( !Scene::init() )
        return false;

    Vec2 origin = Director::getInstance()->getWinSize()/2;

    _crashingLabel = Label::createWithTTF("0", "fonts/Marker Felt.ttf", 120);
    _crashingLabel->setColor(cocos2d::Color3B(200 ,200, 200));
    addChild(_crashingLabel, 1);
                   }, 1, CC_REPEAT_FOREVER, 0, "repeat");
    return true;

My amateur debugging shows that the crash happens when, in the Label::draw method, once in a while the size of batchNodes is 2 and batchCommands is 1 and this block is entered. (In non-crashing cases both are equal to 1, except for the first draw).

if (_batchCommands.size() != _batchNodes.size())

I think we are over-releasing the commands’ PipelineDescriptor’s programState, which has been cloned but not retained.

Ah wait. Do the batch commands correspond to the characters in the label? In that case, it’s strange since the crash always happens at 7.

Adding CC_SAFE_RETAIN(cp); in the *ProgramState::clone() method prevents the crash, but makes some of the labels disappear (like on Android. I’m testing on iOS all the time). 7,8 and 9 disappear, but 10 shows up. Seems extending the batch commands vector happens too soon (?).
And I don’t know yet about the potential leaks.

But I forgot that creating the object sets the reference count to 1. So additional retaining is not the solution. But then, why is the reference count wrong?

Gee, I really could use some course on lower-level stuff like that. :frowning:

Nope. With retaining in the clone() method it also crashes randomly with the following stack trace:

Thread 1 Queue : (serial)
#0	0x0000000191963e40 in nanov2_allocate_from_block$VARIANT$mp.cold.1 ()
#1	0x000000019194ad14 in nanov2_allocate_from_block$VARIANT$mp ()
#2	0x0000000191949f98 in nanov2_allocate$VARIANT$mp ()
#3	0x000000019194a480 in nanov2_calloc$VARIANT$mp ()
#4	0x0000000191958924 in malloc_zone_calloc ()
#5	0x0000000191959208 in calloc ()
#6	0x000000019199c97c in _objc_rootAllocWithZone ()
#7	0x00000001bf970fcc in -[MTLToolsBuffer initWithBaseObject:parent:] ()
#8	0x00000001bf9aa2b0 in -[MTLDebugBuffer initWithBuffer:device:options:] ()
#9	0x00000001bf9cb94c in -[MTLDebugDevice newBufferWithLength:options:] ()
#10	0x0000000101b83600 in ___lldb_unnamed_symbol2203$$libMTLCapture.dylib ()
#11	0x000000010057154c in cocos2d::backend::BufferMTL::BufferMTL(id<MTLDevice>, unsigned long, cocos2d::backend::BufferType, cocos2d::backend::BufferUsage) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/renderer/backend/metal/
#12	0x000000010057172c in cocos2d::backend::BufferMTL::BufferMTL(id<MTLDevice>, unsigned long, cocos2d::backend::BufferType, cocos2d::backend::BufferUsage) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/renderer/backend/metal/
#13	0x000000010057ae0c in cocos2d::backend::DeviceMTL::newBuffer(unsigned long, cocos2d::backend::BufferType, cocos2d::backend::BufferUsage) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/renderer/backend/metal/
#14	0x000000010052379c in cocos2d::CustomCommand::createIndexBuffer(cocos2d::backend::IndexFormat, unsigned long, cocos2d::backend::BufferUsage) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/renderer/CCCustomCommand.cpp:85
#15	0x000000010034b5d8 in cocos2d::Label::updateBuffer(cocos2d::TextureAtlas*, cocos2d::CustomCommand&) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCLabel.cpp:1607
#16	0x000000010034b73c in cocos2d::Label::updateEffectUniforms(cocos2d::Label::BatchCommand&, cocos2d::TextureAtlas*, cocos2d::Renderer*, cocos2d::Mat4 const&) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCLabel.cpp:1616
#17	0x000000010034c5dc in cocos2d::Label::draw(cocos2d::Renderer*, cocos2d::Mat4 const&, unsigned int) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCLabel.cpp:1806
#18	0x000000010034ce84 in cocos2d::Label::drawSelf(bool, cocos2d::Renderer*, unsigned int) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCLabel.cpp:1910
#19	0x000000010034cd74 in cocos2d::Label::visit(cocos2d::Renderer*, cocos2d::Mat4 const&, unsigned int) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCLabel.cpp:1892
#20	0x0000000100377fe8 in cocos2d::Node::visit(cocos2d::Renderer*, cocos2d::Mat4 const&, unsigned int) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCNode.cpp:1249
#21	0x00000001003a601c in cocos2d::Scene::render(cocos2d::Renderer*, cocos2d::Mat4 const&, cocos2d::Mat4 const*) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/2d/CCScene.cpp:210
#22	0x0000000100503cd8 in cocos2d::GLView::renderScene(cocos2d::Scene*, cocos2d::Renderer*) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/platform/CCGLView.cpp:494
#23	0x000000010040b924 in cocos2d::Director::drawScene() at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/base/CCDirector.cpp:292
#24	0x000000010040e220 in cocos2d::Director::mainLoop() at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/base/CCDirector.cpp:1392
#25	0x000000010040e270 in cocos2d::Director::mainLoop(float) at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/base/CCDirector.cpp:1403
#26	0x000000010051dfd8 in -[CCDirectorCaller doCaller:] at /Users/kasia/Documents/misc_projects/NiceCleanCocosProject/NiceCleanCococProject/cocos2d/cocos/platform/ios/
#27	0x0000000101da55f8 in -[DYDisplayLinkInterposer forwardDisplayLinkCallback:] ()

I’m about to give up and wait for some hints, boo.

                   }, 1, CC_REPEAT_FOREVER, 0, "repeat");

On this example, can you change to:

                       std::string str = std::to_string(_i);
                   }, 1, CC_REPEAT_FOREVER, 0, "repeat");

Check if there is anything weird going on with the string object memory wise upon crash?
Just a random thought. I have had issues with string references and memory issues in the past.

This is a little concerning. Any chance you can upload the test project somewhere and link it in here? Best thing you can do is add all folders excluding the cocos2d folder and any build folders (meaning don’t include the 3-4GB Android build folders or Win32 build folders etc.). The final archive should be pretty small after that.

If you don’t already have a account, then make one, and you can submit this as an issue in the cocos2dx repository:

Also, have you tried the latest code from the v4 github repository? This may have already been fixed in there. I personally haven’t had any issues at all with v4 on Windows or Android with labels (at least not yet), but I am using the latest source from the v4 github repo.

Looks like this exact issue may have already been reported multiple times along with a possible fix:

Apply the fix from there and see if it helps.

1 Like

Not sure if this will help or not, i have changed this line of code to:
cp->_vertexLayout = std::make_shared<VertexLayout>(*_vertexLayout);

which fixes some 3d mesh issues that i had. But it causes label crashing issue on metal (apple devices).

for my fix i’ve changed the Label::updateBatchCommand function to be like so:

void Label::updateBatchCommand(Label::BatchCommand &batch)
    CCASSERT(_programState, "programState should be set!");

    auto& pipelineDescriptor = batch.textCommand.getPipelineDescriptor();
	setVertexLayout(pipelineDescriptor); // this will set vertex layout for _programState
	// after setting once, just clone from it
    pipelineDescriptor.programState = _programState->clone();

    auto &pipelineShadow = batch.shadowCommand.getPipelineDescriptor();
	pipelineShadow.programState = _programState->clone();

    auto &pipelineOutline = batch.outLineCommand.getPipelineDescriptor();
    pipelineOutline.programState = _programState->clone();

you can try applying these 2 changes and see if it does anything for your problem

Thank you guys, it’s such a pleasure posting questions here.
@R101 thanks, next time the issues will be my place to start. However, those fixes do not work, neither of them.

Hmm, more debugging shows that this IS indeed vector resize issue. But that fix doesn’t seem to work. But obviously it worked for that guy. I’m sure the code’s the same. What am I missing? I’ll keep you posted. Probably some silly mistake of mine.

(Latest GitHub build of cocos does not help).

EDIT: my mistake - I only changed two of the files out of four. So the fix from the first link of @R101 (issue no 20000) prevents the crash on iOS, but makes the labels disappear sometimes, just like on Android. Something’s still missing.

I’ll keep investigating later when I find time.

Darren, thanks, looked promising, but… still crashing.

@tdebock, I’m sorry, I’m not sure I understand what you would have me check? (what can possibly go wrong with a local, created at runtime, string, that is referenced and copied before going out of scope?)

I have opened an issue with this problem:

I had the same issue, I think this bug might be related with font size. It crashed whenever I changed the string of labels that where with createWithTTF. Noticed my font size was 37.5 and when I rounded it, it fixed the problem. Argument does expect a float tho. Also noticed that going over 45 in font size would also cause the same issue. Results may vary using different fonts and label scaling.

I also have this problem and fixed with these 2 updates.
For crash:

For missing character:


@kalika06 hi, please check does follow PR fix your issue, I have test on Android and works fine:

And a update PR about this:

1 Like

I made the font size smaller and it worked, but I’m not sure if this will help.

[quote=“Cshift, post:22, topic:50218”]
I made the font size smaller and it worked, but I’m not sure if this will help.
[/quote] The root cause is the CustomCommand no properly copy or move assign constructor for std::vector resize operation, for detail please see:

1 Like