频率:偶现
平台:ios
Creator版本:1.6.1 release
手机:苹果5S
系统版本:10.3.2 (14F89)
这个问题我自己已经解决了,引擎组的可以看一下,我就不说怎么改了,免得别人说你显摆技术.
可以的话,说下拿块有问题吧,
,好自己先改着
jsb_websocket.cpp
这个文件自己查一下代码,把executeFunctionWithOwner之前都判断一下参数是否合法,另外static_cast后先判断指针是否为空,不为空再使用.还有应该可以直接改executeFunctionWithOwner里面,在使用前都先判断第一个参数是否合法.
bool ScriptingCore::executeFunctionWithOwner(JS::HandleValue owner, const char name, const JS::HandleValueArray& args, JS::MutableHandleValue retVal)
{
bool bRet = false;
bool hasFunc;
JSContext cx = this->_cx;
JS::RootedValue funcVal(cx);
JS::RootedValue ownerval(cx, owner);
JS::RootedObject obj(cx);
if (ownerval.isObject())
obj = ownerval.toObjectOrNull();
do
{
if (JS_HasProperty(cx, obj, name, &hasFunc) && hasFunc) {
if (!JS_GetProperty(cx, obj, name, &funcVal)) {
break;
}
if (funcVal.isNullOrUndefined()) {
break;
}
bRet = JS_CallFunctionValue(cx, obj, funcVal, args, retVal);
if (JS_IsExceptionPending(cx)) {
handlePendingException(cx);
}
}
}while(0);
return bRet;
}
稍改一下这个应该是可以的,好像里面有些小手误.
void js_cocos2dx_WebSocket_finalize(JSFreeOp *fop, JSObject *obj) {
CCLOG(“jsbindings: finalizing JS object %p (WebSocket)”, obj);
WebSocket *cobj = static_cast<WebSocket *>(JS_GetPrivate(obj));
if (cobj)
{
js_proxy_t * p = jsb_get_native_proxy(cobj);
#if not CC_ENABLE_GC_FOR_NATIVE_OBJECTS
auto copy = &p->obj;
JS::RemoveObjectRoot(cx, copy);
#endif
jsb_remove_proxy§;
ScriptingCore::getInstance()->setFinalizing(true);
// Manually close if WebSocket is not closed
if (cobj->getReadyState() != WebSocket::State::CLOSED)
{
cobj->closeAsync();
}
static_cast<JSB_WebSocketDelegate*>(cobj->getDelegate())->release();
cobj->release();
ScriptingCore::getInstance()->setFinalizing(false);
}
}
还有jsb_get_native_proxy,这里可能返回了空指针或野指针.因为宕机出现在这个文件,我只是顺手把所有保护都加上,引起这个宕机最关键的代码应该是这里.
另外,旁观者不要再误读,我这里只是为了解决问题,另外是有人刚好问了,所以才说出解决方案.也没有所谓几层意思.
真是怕了,唉.每次发贴都要解释再三.
请问
android上没问题吗?
这个bug ,如何触发?
目前我这个来自第三方上报,我改后,暂时没有再发现,安卓暂时也没有发现有这个.是偶现的,不过我猜跟销毁流程有关,不过这个当时并没有发生在退出app时.
ios 上周期性的出现 Websocket Failed With Error Error Domain=NSPOSIXErrorDomain Code=57 “Socket is not connected”
cc v.1.6.1-beta.2
lz 有遇到过没?@mm
暂时没有呢,你自己有没有加入心跳机制.最好自己加上心跳检测机制.不过目前看你这个应该不是这些引起的.
记下留备,感谢分享!:)
谢谢反馈
finalize 中缺失的空指针校验是之前已经修复了,可能你们没有拉取最新的 1.6 分支
建议上面 PR 中其他相关的修改也一并合并一下比较好
关于 executeFunctionWithOwner 的问题,也按照你的建议加强了一下
收到,辛苦了.
void PoolManager::destroyInstance()
{
delete s_singleInstance;
s_singleInstance = nullptr;
}
这个写得也有点小问题,刚在查另一个退出宕机问题,暂时是把这个delete s_singleInstance;给注释了.
除了上面那个,我们之前还改了这个,避免退出宕机,其实退出的时候宕机对用户没什么影响,但反映在苹果的统计后台,很碍眼.
void ScriptEngineManager::destroyInstance()
{
/if (s_pSharedScriptEngineManager)
{
delete s_pSharedScriptEngineManager;
s_pSharedScriptEngineManager = nullptr;
}/
}
PoolManager 的实现没问题,如果不 delete 是有泄漏的,根本原因不在这里,可能 Texture2D 的引用出现了问题,这个就要具体重现后分析了。
ScriptEngineManager 也是一样的道理
退出时的崩溃问题我们在 1.6 之后基本都修复了,至少我们的测试中没有重现过类似的问题了,我感觉你们的一些用法还是我们没有覆盖到,很难说是什么问题
好的,我们也查了,发现这里本身的写法有点点小瑕疵,但都不会引起宕机,可能是其它原因,但目前避免宕机最有效的方式还是注释这些destroyInstance();
附小瑕疵:
void PoolManager::destroyInstance()
{
delete s_singleInstance;
s_singleInstance = nullptr;
}
应该写为:
void PoolManager::destroyInstance()
{
if(s_singleInstance != nullptr)
{
delete s_singleInstance;
s_singleInstance = nullptr;
}
}
嗯是的,这样写更安全。
不过如果真出现PoolManager::destroyInstance两次被调用,也得查查为什么地方引起的。

