宕机BUG:Cocos Creator 1.6宕机

在正常点击界面之间发生的宕机.偶现的.

@panda

你一直对panda不敬,还敢叫他给你解决问题:imp:

呵呵,呵呵,呵呵呵呵

谢谢反馈,估计要下周给你答复

你这里的调用栈貌似不完整,具体崩溃位置在哪句代码呢?setPosition 那几处没有问题,不会导致崩溃,我需要看到最终的崩溃调用才能确定,这个有什么重现步骤或者方法吗?

JSB 中的野指针问题主要是因为我们要手动同步 C++ 和 JS 对象的生命周期,而且 JS 对象的生命周期又是由 GarbageCollection 控制的,我们无法控制,至于具体是什么原因,要具体情况具体分析

P.S. @xjlong 技术讨论很正常,对技术方案有不同的理解和选择也很正常, 只要是愿意跟我们反馈问题,我们都会积极处理

1赞

是个好方法。

那再反映个bug给你们,龙骨动画会导致崩溃的问题,在1.5版本都没有修复(暂不清楚1.6版本是否有),具体表现:在场景中加了一个龙骨动画,会频繁导致进下个场景时崩溃,在游戏中也频繁会崩溃(5局麻将必然崩一次),崩溃的点很多(像是龙骨动画把内存弄乱了样,各处崩溃),把这个龙骨动画去了一切都ok了,奇特的是,最后我们项目组把这个龙骨动画复制了二份放场景里(相当于一个是active=true,一个active=false),也不崩溃了!

龙骨的问题应该已经不会出现了。

强制 GC 是个办法,可能可以提升概率

安卓连出四次闪退问题汇总.这些推栈根本很难看出哪里的问题,反正就是出现了野指针.

大概看了一下CCNode.js的代码,这里的问题主要是_sgNode,我想这个_sgNode代表不同的平台不同实现,这里在JSB环境下,应该是C++中的Node,如果这样理解没错,js中的cc.Node如果被引用,但_sgNode被销毁了,js中的cc.Node并没有销毁,这里_sgNode就变成了野指针,如果要临时解决,在所有使用_sgNode之前都用cc.isObjectValid()先判断是不是已经销毁,如果销毁了就返回.如果在C++层可以判断也是一样的.因为这个BUG是偶现的,如果这样只要不闪退,用户层就是无感知的,而且这种BUG我估计很难查.

当你一筹莫展,无从下手的情况下,加个参数效验就能解决问题.:grin:

还有一个思路,我看了CCNode.js在_onPreDestroy的时候有把_sgNode=null,这里出现了野指针应该是C++代码里多调用了release.另一个思路就是C++代码里真正delete时发一个事件,通知js这边,js得到事件以后把_sgNode=null,这样出现错误只会报一个脚本错误,而不会闪退,当然前提是你这个错误错误不出现在start onDisable等里面(这里面会死循环).所以我建议先用这个思路解决问题,这样要修改的代码不多,实现起来很容易,解决问题很彻底.

这个是在 spriteFrame.getTexture() 调用的时候崩溃,创建或者获取 texture 的 js 对象时失败。

检查 sgNode.isRunning() 的时候崩溃

sgNode.getParent() 崩溃

在 touchend 事件中调用 label.setString() 崩溃

不过从 binary 的调用栈中确实还缺失很多信息,如果你这边不愿意用 default 或者 link + Android Studio 的话,还麻烦给我们发一个 demo,这样我们可以自己重现并解决。因为这些问题跟游戏逻辑的关联性很大,有一些情况可能是我们没有预料到的

安卓的default我们都配置好了,就是编译不过,苹果发了default版但bugly抓不到闪退信息,回退了,下周再试一试。

会不会是用 default 版不闪退?:joy:

不是,半天闪了两次。

0 mimipoker-mobile js_cocos2dx_Node_setVisible(JSContext*, unsigned int, JS::Value*) + 132
1 mimipoker-mobile js_cocos2dx_Node_setVisible(JSContext*, unsigned int, JS::Value*) + 128
2 mimipoker-mobile js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 304
3 mimipoker-mobile ScriptingCore::handleTouchEvent(void*, cocos2d::EventTouch::EventCode, cocos2d::Touch*, cocos2d::Event*, JS::MutableHandleJS::Value) + 676
4 mimipoker-mobile ScriptingCore::handleTouchEvent(void*, cocos2d::EventTouch::EventCode, cocos2d::Touch*, cocos2d::Event*) + 72
5 mimipoker-mobile std::__1::function<void (cocos2d::Touch*, cocos2d::Event*)>::operator()(cocos2d::Touch*, cocos2d::Event*) const + 44
6 mimipoker-mobile _ZNSt3__110__function6__funcIZN7cocos2d15EventDispatcher18dispatchTouchEventEPNS2_10EventTouchEE3$3NS_9allocatorIS6_EEFbPNS2_13EventListenerEEEclEOSA + 300
7 mimipoker-mobile std::__1::function<bool (cocos2d::EventListener*)>::operator()(cocos2d::EventListener*) const + 40
8 mimipoker-mobile cocos2d::EventDispatcher::dispatchEventToListeners(cocos2d::EventDispatcher::EventListenerVector*, std::__1::function<bool (cocos2d::EventListener*)> const&) + 216
9 mimipoker-mobile cocos2d::EventDispatcher::dispatchTouchEvent(cocos2d::EventTouch*) + 364
10 mimipoker-mobile cocos2d::EventDispatcher::dispatchEvent(cocos2d::Event*) + 208
11 mimipoker-mobile cocos2d::GLView::handleTouchesOfEndOrCancel(cocos2d::EventTouch::EventCode, int, long*, float*, float*) + 388
12 mimipoker-mobile -[CCEAGLView touchesEnded:withEvent:] + 500
13 UIKit -[UIWindow _sendTouchesForEvent:] + 2480
14 UIKit -[UIWindow sendEvent:] + 3192
15 UIKit -[UIApplication sendEvent:] + 340
16 UIKit ___dispatchPreprocessedEventFromEventQueue + 2400
17 UIKit ___handleEventQueue + 4268
18 UIKit ___handleHIDEventFetcherDrain + 148
19 CoreFoundation _CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 24
20 CoreFoundation ___CFRunLoopDoSources0 + 540
21 CoreFoundation ___CFRunLoopRun + 744
22 CoreFoundation CFRunLoopRunSpecific + 424
23 GraphicsServices GSEventRunModal + 100
24 UIKit UIApplicationMain + 208
25 mimipoker-mobile main + 108
26 libdyld.dylib _start + 4

苹果闪退又来了,换了个位置.这两天只出现了这一次.刚又现现了一次,两次了.
这个闪退可能跟我的这个代码有关,就是可能这个对象已经destroy了,但是cc.find还能找到.

安卓宕机又出现了新位置.一次给你报五条.

我开始怀疑另一个地方,就是onDestroy时,其实对象已经销毁,这跟C++的实现不一样,C++的release以后,只会在下一帧去销毁对象,在原理上保证了一定的安全性.但在js层,完全没有了这样一层优雅的保护,我怀疑是不是destroy以后还去调用了这个对象的API导致的宕机.其实也建议类似C++层的设计在destroy时不销毁对象,因为在destroy以后可能有些代码还在引用这个对象,而在下一帧去销毁,可以达到保护的目的,这也是C++层优良的设计之一.