运行一段时间Crash

谁帮我看看这个log
多个Sprite在运行多个Action(包括Sequnece, Spawn等等)之后会产生crash

第一种
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
r0 00000000 r1 00000a08 r2 00000006 r3 00000000
r4 00000006 r5 00000002 r6 00000a08 r7 0000010c
r8 00000006 r9 55a41f28 sl 400a2a04 fp 55b3f8e8
ip 00000003 sp 55b3f858 lr 40054261 pc 400631a4 cpsr 00000010

backtrace:
#00 pc 000261a4 /system/lib/libc.so (tgkill+12)
#01 pc 0001725d /system/lib/libc.so (pthread_kill+48)
#02 pc 00017471 /system/lib/libc.so (raise+10)
#03 pc 000161a5 /system/lib/libc.so
#04 pc 00025a54 /system/lib/libc.so (abort+4)
#05 pc 000154dc /system/lib/libc.so (dlfree+2344)
#06 pc 0000e178 /system/lib/libc.so (free+20)
#07 pc 005057d4 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (cocos2d::ccArrayFree(cocos2d::_ccArray*&)+76)
#08 pc 00289f60 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (cocos2d::ActionManager::deleteHashElement(cocos2d::_hashElement*)+36)
#09 pc 00290a18 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (cocos2d::ActionManager::update(float)+512)
#10 pc 004a6070 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}::operator()(float) const+28)
#11 pc 004a5f94 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (std::__1::__function::__func<void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}, std::__1::allocator<{lambda(float)#1}>, void (float)>::operator()(float&&)+72)
#12 pc 004dfe98 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (std::__1::function<void (float)>::operator()(float) const+60)
#13 pc 004edf5c /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (cocos2d::Scheduler::update(float)+172)
#14 pc 0049d374 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (cocos2d::Director::drawScene()+200)
#15 pc 004a1e50 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (cocos2d::DisplayLinkDirector::mainLoop()+80)
#16 pc 006e1804 /data/app-lib/com.zzdc.joyray-1/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender+28)
#17 pc 0001e94c /system/lib/libdvm.so (dvmPlatformInvoke+112)
#18 pc 0004fcb9 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)
#19 pc 00000214 /dev/ashmem/dalvik-jit-code-cache (deleted)

第二种
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
r0 56f74058 r1 3e82f69e r2 00000000 r3 3e82f69e
r4 4cc32de8 r5 559aaae0 r6 00000000 r7 559e6f30
r8 55ae4b00 r9 559e6f28 sl 559aaaf0 fp 55ae47e8
ip 7b47adfa sp 55ae47d8 lr 550dc378 pc 00000000 cpsr 20070010

backtrace:
#00 pc 00000000
#01 pc 0027e374 /system/lib/libcocos2dcpp.so (cocos2d::Spawn::update(float)+72)
#02 pc 0027e374 /system/lib/libcocos2dcpp.so (cocos2d::Spawn::update(float)+72)
#03 pc 0027c904 /system/lib/libcocos2dcpp.so (cocos2d::Sequence::update(float)+848)
#04 pc 0027ba08 /system/lib/libcocos2dcpp.so (cocos2d::ActionInterval::step(float)+864)
#05 pc 002906f0 /system/lib/libcocos2dcpp.so (cocos2d::ActionManager::update(float)+248)
#06 pc 004a5e50 /system/lib/libcocos2dcpp.so (void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}::operator()(float) const+28)
#07 pc 004a5d74 /system/lib/libcocos2dcpp.so (std::__1::__function::__func<void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}, std::__1::allocator<{lambda(float)#1}>, void (float)>::operator()(float&&)+72)
#08 pc 004dfc78 /system/lib/libcocos2dcpp.so (std::__1::function<void (float)>::operator()(float) const+60)
#09 pc 004edd3c /system/lib/libcocos2dcpp.so (cocos2d::Scheduler::update(float)+172)
#10 pc 0049d154 /system/lib/libcocos2dcpp.so (cocos2d::Director::drawScene()+200)
#11 pc 004a1c30 /system/lib/libcocos2dcpp.so (cocos2d::DisplayLinkDirector::mainLoop()+80)
#12 pc 006e15e4 /system/lib/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender+28)
#13 pc 0001e94c /system/lib/libdvm.so (dvmPlatformInvoke+112)
#14 pc 0004fcb9 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)
#15 pc 00000214 /dev/ashmem/dalvik-jit-code-cache (deleted)

stack:
55ae4798 00000000
55ae479c 40117b70 /system/lib/libc.so (dlmalloc+532)
55ae47a0 56942310
55ae47a4 56942318
55ae47a8 00000000
55ae47ac 00000000
55ae47b0 56029330
55ae47b4 40119ff0 /system/lib/libc.so (dlfree+1084)
55ae47b8 00051e8c
55ae47bc 55ae47ec
55ae47c0 00000000
55ae47c4 4038c571 /system/lib/libgui.so
55ae47c8 55ae47ec
55ae47cc 00000df7
55ae47d0 55ae47e8
55ae47d4 00000000
#00 55ae47d8 00000001
… …
#01 55ae47d8 00000001
55ae47dc 559af598
55ae47e0 3e82f69e
55ae47e4 559af598
55ae47e8 55ae4800
55ae47ec 550dc378 /system/lib/libcocos2dcpp.so (cocos2d::Spawn::update(float)+76)
#02 55ae47f0 550d9694 /system/lib/libcocos2dcpp.so (cocos2d::ActionInterval::isDone() const+28)
55ae47f4 56032d48
55ae47f8 3e82f69e
55ae47fc 56032d48
55ae4800 55ae4858
55ae4804 550da908 /system/lib/libcocos2dcpp.so (cocos2d::Sequence::update(float)+852)
#03 55ae4808 5602a290
55ae480c 5602a290
55ae4810 00000000
55ae4814 00000002
55ae4818 aba0d40c
55ae481c 5602a290
55ae4820 00005024
55ae4824 5602abb0
55ae4828 00000000
55ae482c 5602a290
55ae4830 00000000
55ae4834 00000000
55ae4838 00000000
55ae483c 3f800000
55ae4840 3e82f69e
55ae4844 57b0ce48
… …
#04 55ae4860 3e82f69e
55ae4864 3e82f69e
55ae4868 3e82f69e
55ae486c 3da3d6fd
55ae4870 3da3d6fd
55ae4874 00000001
55ae4878 34000000
55ae487c 3da3d6fd
55ae4880 3ca7a205
55ae4884 00000000
55ae4888 3f800000
55ae488c 3e82f69e
55ae4890 3da3d6fd
55ae4894 3da3d6fd
55ae4898 00000001
55ae489c 34000000
… …
#05 55ae4910 55ae4930
55ae4914 5695e7f8
55ae4918 00000002
55ae491c 56042d18
55ae4920 54272e20 /system/lib/libMali.so
55ae4924 57b0e170
55ae4928 3ca7a205
55ae492c 56042d18
55ae4930 55ae4940
55ae4934 55303e54 /system/lib/libcocos2dcpp.so (void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}::operator()(float) const+32)
#06 55ae4938 3ca7a205
55ae493c 560422e4
55ae4940 55ae4970
55ae4944 55303d78 /system/lib/libcocos2dcpp.so (std::__1::__function::__func<void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}, std::__1::allocator<{lambda(float)#1}>, void (float)>::operator()(float&&)+76)
#07 55ae4948 50d4d800
55ae494c 55ae497c
55ae4950 560422e0
55ae4954 560422e4
55ae4958 560422e4
55ae495c 55ae497c
55ae4960 560422e4
55ae4964 560422e4
55ae4968 55ae497c
55ae496c 55ae497c
55ae4970 55ae4988
55ae4974 5533dc7c /system/lib/libcocos2dcpp.so (std::__1::function<void (float)>::operator()(float) const+64)
#08 55ae4978 55303d2c /system/lib/libcocos2dcpp.so (std::__1::__function::__func<void cocos2d::Scheduler::scheduleUpdatecocos2d::ActionManager(cocos2d::ActionManager*, int, bool)::{lambda(float)#1}, std::__1::allocator<{lambda(float)#1}>, void (float)>::operator()(float&&))
55ae497c 3ca7a205
55ae4980 560422e0
55ae4984 55ae497c
55ae4988 55ae4ab0
55ae498c 5534bd40 /system/lib/libcocos2dcpp.so (cocos2d::Scheduler::update(float)+176)
#09 55ae4990 50d4d800
55ae4994 54274fc8 /system/lib/libMali.so
55ae4998 54272e20 /system/lib/libMali.so
55ae499c 00000001
55ae49a0 50d4d800
55ae49a4 54274fc8 /system/lib/libMali.so
55ae49a8 56042c68
55ae49ac 00000001
55ae49b0 4016abc8
55ae49b4 541d5ef0 /system/lib/libMali.so
55ae49b8 54274fc4 /system/lib/libMali.so
55ae49bc 54274fc8 /system/lib/libMali.so
55ae49c0 40417e50 /system/lib/libEGL.so
55ae49c4 00000000
55ae49c8 55ae49e4
55ae49cc 00000000
… …
#10 55ae4ab8 fffffe8c
55ae4abc 00000001
55ae4ac0 34000000
55ae4ac4 3ca7a205
55ae4ac8 56042740
55ae4acc 5574fb20 /system/lib/libcocos2dcpp.so
55ae4ad0 56042740
55ae4ad4 56042740
55ae4ad8 55ae4ae8
55ae4adc 552ffc34 /system/lib/libcocos2dcpp.so (cocos2d::DisplayLinkDirector::mainLoop()+84)
#11 55ae4ae0 56042740
55ae4ae4 56042740
55ae4ae8 55ae4af8
55ae4aec 5553f5e8 /system/lib/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender+32)
#12 55ae4af0 418c5c60 /system/lib/libdvm.so
55ae4af4 559aa978
55ae4af8 55ae4b14
55ae4afc 41828950 /system/lib/libdvm.so (dvmPlatformInvoke+116)
#13 55ae4b00 559e6f28
55ae4b04 00000001
55ae4b08 00000000
55ae4b0c 41cb66d8 /dev/ashmem/dalvik-heap (deleted)
55ae4b10 00000000
55ae4b14 41859cbd /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+488)
#14 55ae4b18 559e6f28
55ae4b1c 54abb060 /data/dalvik-cache/system@app@JRLauncher_FIH_4.0020.01.apk@classes.dex
55ae4b20 5553f5c8 /system/lib/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender)
55ae4b24 559aaaf0
55ae4b28 0000002c
55ae4b2c 4016abc8
55ae4b30 41d00001 /dev/ashmem/dalvik-heap (deleted)
55ae4b34 00000000
55ae4b38 559aab08
55ae4b3c 4016abc8
55ae4b40 559aab08
55ae4b44 41887bb5 /system/lib/libdvm.so (dvmCompilerWorkEnqueue(unsigned short const*, WorkOrderKind, void*)+148)
55ae4b48 559aaae0
55ae4b4c 559aaae0
55ae4b50 57b09e70
55ae4b54 418c5c60 /system/lib/libdvm.so
… …
#15 55ae4c30 00000000
55ae4c34 559aaae0
55ae4c38 fffffea4
55ae4c3c 559aaae0
55ae4c40 55ae4d78
55ae4c44 00000000
55ae4c48 00000000
55ae4c4c 55ae4c84
55ae4c50 41cb7118 /dev/ashmem/dalvik-heap (deleted)
55ae4c54 41839334 /system/lib/libdvm.so (dvmMterpStd(Thread*)+80)
55ae4c58 00000000
55ae4c5c 00000000
55ae4c60 00000000
55ae4c64 00000000
55ae4c68 00000000
55ae4c6c 418392e4 /system/lib/libdvm.so (dvmMterpStd(Thread*))

顺便再指导一下小弟如何看这样的Log吧。

1.什么问题?

看贴出的函数堆栈可以初步确定的是对Action的控制不够,这种情况一般是出现在混用多种运动,但是却没注意调用者的生命周期。

建议贴出代码。或者逐步缩小代码规模调试。

2.如何看?

http://www.cocoachina.com/bbs/read.php?tid-195644.html

版主大神,版主大哥,下面的帖子我看了,但是您说的『对Action的控制不够』,这个有什么好的建议么? 我有在runAction之前stopAllActions啊。能否再指点一二呢?

主要是以下的代码,并且会频繁调用。

void PetSprite::animateToPose(std::string &poseName, float duration)
{
ValueMap& poseMap = mPosesValueMap.asValueMap();
if(poseMap.size() > 0){
bool firstObj = true;
for (auto modelPart = mModelPartsMap.begin(); modelPart != mModelPartsMap.end(); modelPart ++) {
std::string partName = modelPart->first;
auto partSprite = modelPart->second;
int tag = partSprite->getTag();
if(tag == PART_OBJ_ANIMATION_TAG || tag == PART_OBJ_ANIMATION_TAG2){
//describe the part position and anim informations
ValueMap posePartMap;
//if part name in pose, use pose anim, others use standy pose
if(poseMap.count(partName) > 0){
posePartMap = poseMap.asValueMap();
}else{
posePartMap = mPosesValueMap"standby"].asValueMap().asValueMap();
}

            //set up frames
            ValueVector partFrameArray = posePartMap"frames"].asValueVector();
            bool singleFrame = partFrameArray.size() > 1 ? false : true;
            Animation *partSpriteAnimation;
            if(tag == PART_OBJ_ANIMATION_TAG){
                if(singleFrame){
                    std::string frameName = PetPrefs::getInstance()->getDecorTools(partName);
                    if(frameName == DECORATION_EMPTY){
                        frameName = partFrameArray.at(0).asString();
                    }
                    
                    SpriteFrame *partFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName(frameName);
                    if(partFrame){
                        partSprite->setSpriteFrame(partFrame);
                    }
                    
                    partSpriteAnimation = nullptr;
                }else{
                    Vector<SpriteFrame *> *animPartFrames;
                    for (auto frame : partFrameArray) {
                        std::string frameName = frame.asString();
                        animPartFrames->pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName(frameName));
                    }
                    
                    float delay = duration / partFrameArray.size();
                    partSpriteAnimation = Animation::createWithSpriteFrames(*animPartFrames, delay, 0);
                }
            }
            
            //set up positions
            ValueMap partPosMap = posePartMap"position"].asValueMap();
            float x = partPosMap"x"].asFloat();
            float y = partPosMap"y"].asFloat();
            
            Vec2 newPosition =  Vec2(x, y);
            
            //rotation
            float partRotation = posePartMap"rotation"].asFloat();
            
            //scale x and scale y
            float scaleX = posePartMap"scale"].asValueMap()"x"].asFloat();
            float scaleY = posePartMap"scale"].asValueMap()"y"].asFloat();
            
            partSprite->stopAllActions();
            
            Spawn *partSpriteActions;
            auto moveTo = MoveTo::create(duration, newPosition);
            auto rotateTo = RotateTo::create(duration, partRotation);
            auto scaleTo = ScaleTo::create(duration, scaleX, scaleY);
            
            if(singleFrame){
                partSpriteActions = Spawn::create(moveTo, rotateTo, scaleTo, nullptr);
            }else{
                partSpriteActions = Spawn::create(moveTo, rotateTo, scaleTo, partSpriteAnimation, nullptr);
            }
            
            if(firstObj){
                firstObj = false;
                auto callFunc = CallFunc::create(CC_CALLBACK_0(PetSprite::movementPoseUpdate, this));
                partSprite->runAction(Sequence::create(partSpriteActions, callFunc, nullptr));
            }else{
                partSprite->runAction(partSpriteActions);
            }
        }
    }
}

『对Action的控制不够』,这个有什么好的建议么?

你要能清楚的知道引擎的在每一帧,你创建的对象的状态(比如每一帧他是在做什么运动,要不要停止,到了触发回调的时候了吗,要不要切换动作,而不是等逻辑一复杂了就stopAllActions)。特别是调用者的生命周期。这是游戏逻辑层的东西了。你的代码很多变量我都不知道是干嘛的,建议注释掉部分代码进行排查。

只能说C++不适合初学者使用,还是用lua吧

我也是被赶鸭子上架的,我是做java的。。。。。对C++仅仅停留在阅读的层面。。这些代码是我硬着头皮写的。。。

谢谢版主的耐心解答。:5:
只有一个界面,所有的Sprite我没有进行release,给Sprite run一个新的action的时候,我就调用了一个stopAllActions。。。。

版主大神,我stopAllAction是为了给这个Sprite重新run一个action啊。我这边好多出错,但是都是报在cocos2dx的libcocos2dcpp.so中
比如这一种Log
pid: 12611, tid: 12628, name: Thread-228 >>> com.zzdc.joyray <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
Stack frame #00 pc 00000000
Stack frame #01 pc 0027e3f4 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (cocos2d::Spawn::startWithTarget(cocos2d::Node*)+88)
Stack frame #02 pc 0027e3f4 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (cocos2d::Spawn::startWithTarget(cocos2d::Node*)+88)
Stack frame #03 pc 0028d428 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (cocos2d::ActionManager::addAction(cocos2d::Action*, cocos2d::Node*, bool)+6640)
Stack frame #04 pc 0031bc74 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (cocos2d::Node::runAction(cocos2d::Action*)+220)
Stack frame #05 pc 0019b93c /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (PetSprite::animateToPose(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >&, float)+4476)
Stack frame #06 pc 0019c090 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (PetSprite::movementPoseUpdate()+416)
Stack frame #07 pc 0019ccc4 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (PetSprite::setMovement(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >&)+648)
Stack frame #08 pc 0019c6dc /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (PetSprite::setState(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >&)+1312)
Stack frame #09 pc 0019ddd4 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (PetSprite::triggerWithAction(char const*)+880)
Stack frame #10 pc 00187598 /data/app-lib/com.zzdc.joyray-2/libcocos2dcpp.so (Java_com_zzdc_joyray_PetTrigger_triggerAction+340)

这些都不是必现,就是在之前的动作在运行的时候,要换一个Action,这个时候我才调用stopAllAction然后在create响应的Action,执行runaction。

有办法给我一个简单重现的例子吗?

网事版主大神,我这两天终于做了一个demo能够重现问题了,请问如何将代码给你呢?

我用你给的那个ndk_stack的连接试了,每次log都不一样,但是主要就集中在ActionManager 、Ref release、Spawn update等这几个方面。

网事大神,请问我怎么把重现例子的代码给你呢?

网事大神你好,重现代码如下
Java层触发JNI 代码执行cocos2dx方法:
Java代码为:
public static native void test();

JNI代码为:
extern “C” void Java_org_cocos2dx_cpp_AppActivity_test()
{
log("//////////////////////////////");
HelloWorld * helloWorld = static_cast<HelloWorld *>(scene->getChildByTag(1));
helloWorld->click();
}

cocos2dx中的代码为:

void HelloWorld::click()
{
for (int i = 0 ; i < 1000; i++) {
auto rotate = RotateTo::create(1, 180);
auto scale = ScaleTo::create(1, 0.1f);
auto rotate1 = RotateTo::create(1, 0);
auto scale1 = ScaleTo::create(1, 1.f);
auto spawn = Spawn::create(rotate, scale, NULL);
auto spawn1 = Spawn::create(rotate1, scale1, NULL);
auto sequence = Sequence::create(spawn, spawn1, NULL);
_Demosprite->stopAllActions();
_Demosprite->runAction(sequence);
}
}

因为Java层没有触发的地方,我将test()的调用写在@Override
public void onBackPressed() {
//super.onBackPressed();
test();
}

运行成功,然后按back键,则无响应,稍等一会就退出应用而不产生crash dialog。
每次出现的log都不相同

1.和for循环有关系么?(应该是没有关系的)

2.直接在c++层调用click()有问题吗?(应该是没有问题的)

3.如果上面两点确认了,原因应该是不可以在UI线程调用openGL线程的Cocos2d-x相关函数,这样会导致各种各样的crash。

版主大人,

1.for循环没有关系,之所以用for循环是为了让该问题更好的重现

2.直接在C++代码中调用是没有问题的

3.for循环次数比较少的话,则不会crash。 那么我应该如何改进呢? 用类似timer的定时或者设置布尔类型的flag,让update方法去调用,这样不会有问题吧。我尝试了设置布尔参数,不会crash。

谢谢版主耐心给我解答。

转到主线程中去调用,先调用一个全局函数,然后这个全局函数调用performFunctionInCocosThread,在这个的lanbam中去做主线程的操作