1.7.0正式版,1.8.0正式版,1.7.2beta2都会在IOS中频繁闪退,Android中却没事

加好友请求 已发

每日一顶+1

有结果了吗?

每日一顶

jsb2.0对于cpp管理js生命周期的对象,处理的有问题。如果用到了spine, box2d等,可能会导致crash(ios,android和win32都可能crash)。修改后最近几天没有crash过了。最近太忙没时间提交pullrequest,有问题的同学可以自己修改下试试(引擎中有多处)。

文档里的

spTrackEntry_setDisposeCallback([](spTrackEntry* entry){
    // spTrackEntry 的销毁回调
    auto cleanup = [entry](){
        if (!se::ScriptEngine::getInstance()->isValid())
            return;
        se::AutoHandleScope hs;
        se::ScriptEngine::getInstance()->clearException();
        auto iter = se::NativePtrToObjectMap::find(entry);
        if (iter != se::NativePtrToObjectMap::end())
        {
            CCLOG("spTrackEntry %p was recycled!", entry);
            se::Object* seObj = iter->second;
            seObj->clearPrivateData(); // 解除 mapping 关系
            seObj->unroot(); // unroot,使 JS 对象受 GC 管理
            seObj->decRef(); // 释放 se::Object
        }
    };
    // 确保不再垃圾回收中去操作 JS 引擎的 API
    if (!se::ScriptEngine::getInstance()->isGarbageCollecting())
    {
        cleanup();
    }
    else
    { // 如果在垃圾回收,把清理任务放在帧结束中进行
        CleanupTask::pushTaskToAutoReleasePool(cleanup);
    }
});

应该改成类似这样的:

virtual void on_destroyed(void *obj) {        
    auto iter = se::NativePtrToObjectMap::find(obj);
    if (iter == se::NativePtrToObjectMap::end())
        return;
    auto seInstance = se::ScriptEngine::getInstance();
    if (!seInstance->isValid() || seInstance->isInCleanup())
        return;
    se::AutoHandleScope hs;
    seInstance->clearException();
    se::Object* seObj = iter->second;
    seObj->clearPrivateData();
    auto cleanup = [seObj]() {
        auto seInstance = se::ScriptEngine::getInstance();
        if (!seInstance->isValid() || seInstance->isInCleanup())
            return;
        se::AutoHandleScope hs;
        se::ScriptEngine::getInstance()->clearException();
        seObj->unroot();
        seObj->decRef();
    };
    if (!se::ScriptEngine::getInstance()->isGarbageCollecting())
    {
        cleanup();
    }
    else
    {
        CleanupTask::pushTaskToAutoReleasePool(cleanup);
    }
}

你这个修复主要是加入了 seInstance->isInCleanup() ?

你碰到的crash问题主要是在热更新重启游戏的时候么?

还有,你吧 clearPrivateData 移动到cleanup 外面是有问题的,因为如果当前是在 GarbageCollecting,操作任何有关JS VM的接口都可能导致问题的。

主要是把clearPrivateData()放到cleanup()外面。

不是。cpp控制生命周期的对象,反复创建销毁的时候,会出现assert(NativePtrToObjectMap::find(data) == NativePtrToObjectMap::end());失败的问题。

如果一个native对象销毁了,但是正在垃圾回收,那么cleanup会被延迟调用。这期间它之前占用的内存可能会被分配给新的对象,这个新的对象在setPrivateData()的时候就会assert失败。

重现的testcase也很简单,只要重复的“创建native对象,生成相应的SEObject,销毁native对象”就可以了。

这一点我倒是不清楚。不过修改之前是必然crash,修改之后暂时还没crash过。

正在garbage collectiing,是不能操作任何js vm接口,还是只是不能操作clearPrivateData()?
按我的理解,clearPrivateData()只是把js obj的private清空而已,并不会导致js obj被回收,理论应该不会有问题才对?而且代码中很多地方都有setPrivateData()的调用,似乎并没有判断是否正在garbage collecting?
当然我对vm内部不太了解,只是根据相关代码猜测的。

任何有关 JS VM 的包含context接口都不能调用。大部分接口都包含context的。

你反馈的 setPrivateData 触发assert 的确会有问题,这块我考虑一下如何修复更合理。

前面加了se::AutoHandleScope hs;也不可以的吗?

跟HandleScope没关系。

1赞

解决了

https://github.com/cocos-creator/cocos2d-x-lite/pull/1075

并更新了文档内容。

1赞

赞!

有个疑问,在native对象释放后,seobj回收之前,seobj里仍然保留了native对象的指针(野指针),如果js代码恰好在这期间访问了这个对象,会不会crash?

最新1.8.1的安卓有内存泄漏啊,估计是龙骨这块,玩一会儿必定闪退

+1 闪退 卡顿一直存在

@dumganhar ios crash的问题解决了吗? (除了上面clearPrivateData的问题,应该还有别的问题)

嗯,应该。我没继续收到类似反馈。
有问题的可以整理复现方式,我这里会查。

请查收下qq附件 发了一个毕现的崩溃demo
release包 毕现, debug包不崩溃
ios 系统是10.2.1 ipad
xcode:9.2
demo是个jsb-default ios工程
用release的配置Run 就会崩溃

JavaScriptCore	JSObjectCallAsFunction + 308
1 JavaScriptCore	JSObjectCallAsFunction + 68
2 WinningSlots-mobile	__cxa_throw + 484992
3 WinningSlots-mobile	__cxa_throw + 491524
4 WinningSlots-mobile	__cxa_throw + 2045808
5 WinningSlots-mobile	__cxa_throw + 2487704
6 WinningSlots-mobile	__cxa_throw + 2572008
7 WinningSlots-mobile	__cxa_throw + 1037144
8 JavaScriptCore	long long JSC::APICallbackFunction::call<JSC::JSCallbackFunction>(JSC::ExecState*) + 416
9 JavaScriptCore	JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 480
10 JavaScriptCore	_llint_entry + 24744
11 JavaScriptCore	_vmEntryToJavaScript + 264
12 JavaScriptCore	JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
13 JavaScriptCore	JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
14 JavaScriptCore	JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 160
15 JavaScriptCore	JSObjectCallAsFunction + 536
16 WinningSlots-mobile	__cxa_throw + 484992
17 WinningSlots-mobile	__cxa_throw + 1516060
18 JavaScriptCore	long long JSC::APICallbackFunction::call<JSC::JSCallbackFunction>(JSC::ExecState*) + 416
19 JavaScriptCore	JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 480
20 JavaScriptCore	_llint_entry + 24744
21 JavaScriptCore	_llint_entry + 25580
22 JavaScriptCore	_llint_entry + 24660
23 JavaScriptCore	_llint_entry + 25848
24 JavaScriptCore	_llint_entry + 24760
25 JavaScriptCore	_llint_entry + 24760
26 JavaScriptCore	_llint_entry + 24660
27 JavaScriptCore	_llint_entry + 24660
28 JavaScriptCore	_llint_entry + 24660
29 JavaScriptCore	_llint_entry + 24660
30 JavaScriptCore	_vmEntryToJavaScript + 264
31 JavaScriptCore	JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
32 JavaScriptCore	JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
33 JavaScriptCore	JSC::callSetter(JSC::ExecState*, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::ECMAMode) + 320
34 JavaScriptCore	JSC::JSObject::putInlineSlow(JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&) + 2240
35 JavaScriptCore	_llint_slow_path_put_by_id + 908
36 JavaScriptCore	_llint_entry + 11576
37 JavaScriptCore	_llint_entry + 24760
38 JavaScriptCore	_llint_entry + 24760
39 JavaScriptCore	_llint_entry + 24760
40 JavaScriptCore	_llint_entry + 24760
41 JavaScriptCore	_llint_entry + 24660
42 JavaScriptCore	_llint_entry + 24660
43 JavaScriptCore	_vmEntryToJavaScript + 264
44 JavaScriptCore	JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
45 JavaScriptCore	JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
46 JavaScriptCore	JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 160
47 JavaScriptCore	JSObjectCallAsFunction + 536
48 WinningSlots-mobile	__cxa_throw + 484992
49 WinningSlots-mobile	__cxa_throw + 540888
50 WinningSlots-mobile	__cxa_throw + 3068816
51 WinningSlots-mobile	__cxa_throw + 3098984
52 WinningSlots-mobile	__cxa_throw + 3098824
53 WinningSlots-mobile	__cxa_throw + 3082372
54 WinningSlots-mobile	__cxa_throw + 3082268
55 WinningSlots-mobile	__cxa_throw + 3082628
56 WinningSlots-mobile	__cxa_throw + 2393456
57 WinningSlots-mobile	__cxa_throw + 2400908
58 QuartzCore	CA::Display::DisplayLinkItem::dispatch(unsigned long long) + 44
59 QuartzCore	CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 444
60 IOKit	IODispatchCalloutFromCFMessage + 372
61 CoreFoundation	___CFMachPortPerform + 180
62 CoreFoundation	___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56
63 CoreFoundation	___CFRunLoopDoSource1 + 436
64 CoreFoundation	___CFRunLoopRun + 1840
65 CoreFoundation	CFRunLoopRunSpecific + 444
66 GraphicsServices	GSEventRunModal + 180
67 UIKit	-[UIApplication _run] + 684
68 UIKit	UIApplicationMain + 208
69 WinningSlots-mobile	0x0000000100058000 + 50760
70 libdyld.dylib	_start + 4
JavaScriptCore	_llint_slow_path_jfalse + 352
1 JavaScriptCore	_llint_slow_path_jfalse + 52
2 JavaScriptCore	_llint_entry + 23928
3 JavaScriptCore	_llint_entry + 26912
4 JavaScriptCore	_llint_entry + 26912
5 JavaScriptCore	_llint_entry + 26912
6 JavaScriptCore	_llint_entry + 26912
7 JavaScriptCore	_llint_entry + 26912
8 JavaScriptCore	_vmEntryToJavaScript + 272
9 JavaScriptCore	JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 184
10 JavaScriptCore	JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 400
11 JavaScriptCore	JSC::callSetter(JSC::ExecState*, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::ECMAMode) + 280
12 JavaScriptCore	JSC::JSObject::putInlineSlow(JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&) + 920
13 JavaScriptCore	_llint_slow_path_put_by_id + 880
14 JavaScriptCore	_llint_entry + 12112
15 JavaScriptCore	_llint_entry + 26912
16 JavaScriptCore	_llint_entry + 26912
17 JavaScriptCore	_llint_entry + 27012
18 JavaScriptCore	_llint_entry + 27012
19 JavaScriptCore	_llint_entry + 26912
20 JavaScriptCore	_llint_entry + 26912
21 JavaScriptCore	_vmEntryToJavaScript + 272
22 JavaScriptCore	JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 184
23 JavaScriptCore	JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 400
24 JavaScriptCore	JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 168
25 JavaScriptCore	JSObjectCallAsFunction + 392
26 WinningSlots-mobile	__cxa_throw + 484992
27 WinningSlots-mobile	__cxa_throw + 540888
28 WinningSlots-mobile	__cxa_throw + 3068816
29 WinningSlots-mobile	__cxa_throw + 3098984
30 WinningSlots-mobile	__cxa_throw + 3098824
31 WinningSlots-mobile	__cxa_throw + 3082372
32 WinningSlots-mobile	__cxa_throw + 3082268
33 WinningSlots-mobile	__cxa_throw + 3082628
34 WinningSlots-mobile	__cxa_throw + 2393456
35 WinningSlots-mobile	__cxa_throw + 2400908
36 QuartzCore	CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 672
37 IOKit	IODispatchCalloutFromCFMessage + 392
38 CoreFoundation	___CFMachPortPerform + 188
39 CoreFoundation	___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56
40 CoreFoundation	___CFRunLoopDoSource1 + 440
41 CoreFoundation	___CFRunLoopRun + 2196
42 CoreFoundation	CFRunLoopRunSpecific + 436
43 GraphicsServices	GSEventRunModal + 100
44 UIKit	UIApplicationMain + 236
45 WinningSlots-mobile	0x0000000102320000 + 50760
46 libdyld.dylib	_start + 4

这几个崩溃概率挺高的,在ios上收到了几百个这些崩溃日志。。。具体原因不知道,出现位置也不是必现的,连着手机的时候崩溃过,但都崩在jsc的汇编上了,没有源代码调试。@dumganhar