IOS退出必现崩溃的分析及临时解决办法

重现方法

论坛中已经很多人反馈了,重现方法很简单:

  • 运行程序,然后强制退出
  • 崩溃出现这里:
void ScriptingCore::cleanAllScript()
{
    filename_script.clear();			// 这里崩溃
}

原因分析

  • 先看调用堆栈:
    ScriptingCore::cleanAllScript
    ScriptingCore::cleanup
    ScriptingCore::~ScriptingCore
    ScriptEngineManager::removeScriptEngine
    ScriptEngineManager::~ScriptEngineManager
    ScriptEngineManager::destroyInstance
    AppDelegate::~AppDelegate

  • 再看AppDelegate的声明,在AppController.mm里面:static AppDelegate s_sharedApplication;,它是一个全局静态变量。

  • 看来看filename_script的声明,在ScriptingCore.cpp里面:static std::unordered_map<std::string, JS::PersistentRootedScript*> filename_script;,它也是一个全局静态变量。

  • 看出问题了吗?在C++里面全局对象的析构是不可预期的,这里明显filename_script要早于AppDelegate析构掉,所以等到AppDelegate析构时调用到filename_script.clear(),就出现释放野指针的错误了。

临时解决方法

干脆把在AppDelegate中把ScriptEngineManager::destroyInstance();注释掉,毕竟在程序结束时,由系统去回收资源也挺合理的。

修改后测试还是出错,AppDelegate的父类ApplicationProtocol在析构时也会去调用这个函数,把ApplicationProtocol中的ScriptEngineManager::destroyInstance();也给注释掉。

最后程序正常的退出了。

当然上面的方法是我的临时办法,在官方正式解决之前,可以先用着:)

@panda @jare

1赞

下面这些贴子的反馈崩溃的原因大概也是这个导致的:
http://forum.cocos.com/t/cocos-creator-v1-6-0-8-11-rc-1/48681/728

这个问题,1.4版本就开始有了!
当初说1.6解决,结果还是一样的!
IOS退出奔溃问题!

怪不得这么多崩溃报告 总是能在楼主的帖子中找到很多好东西:smile:

其实只要在XCode上真机运行过,应该都会遇到这个问题。不连XCode跑退出的话,感觉不出来的。
IOS那个时机去清理对象是有点晚了,好多静态对象都被释放了。还不如直接给系统去回收算了。

你是什么平台测试的?我们这次有测试关闭和重启,按理说不应该有问题才对

连上XCode真机调试就会出现的。运行程序,然后强制退出,就是双击一个Home键,把程序划掉那种操作。

嗯,我重现了,问题就是你说的

感谢,1.6.1 中会修复的

修复方案在这里

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

1赞

赞,速度真快,直接用官方的方案

这样子的话,自己要弄个版本管理cocos的代码,工作量又上升了。

你这个改完之后 模拟器编译不出来了

:clap:

报错吗?

/Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/Classes/ide-support/RuntimeJsImpl.cpp:219:70: error: no viable conversion from ‘std::unordered_map<std::string, JS::PersistentRootedScript *> *’ (aka ‘unordered_map<basic_string<char, char_traits, allocator >, PersistentRooted<JSScript *> *> *’) to ‘std::unordered_map<std::string, JS::PersistentRootedScript *>’ (aka 'unordered_map<basic_string<char, char_traits, allocator >, PersistentRooted<JSScript *> >’)
std::unordered_map<std::string, JS::PersistentRootedScript
> filenameScript = ScriptingCore::getInstance()->getFileScript();
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/Classes/ide-support/RuntimeJsImpl.cpp:9:
In file included from /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/proj.ios_mac/…/…/…/…/…/cocos/base/CCDirector.h:38:
In file included from /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/proj.ios_mac/…/…/…/…/…/cocos/2d/CCScene.h:32:
In file included from /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/proj.ios_mac/…/…/…/…/…/cocos/2d/CCNode.h:35:
In file included from /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/proj.ios_mac/…/…/…/…/…/cocos/base/CCProtocols.h:34:
In file included from /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/proj.ios_mac/…/…/…/…/…/cocos/renderer/CCTexture2D.h:32:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/include/c++/v1/unordered_map:823:5: note: candidate constructor not viable: no known conversion from ‘std::unordered_map<std::string, JS::PersistentRootedScript *> *’ (aka ‘unordered_map<basic_string<char, char_traits, allocator >, PersistentRooted<JSScript *> *> *’) to ‘const std::__1::unordered_map<std::__1::basic_string, JS::PersistentRooted<JSScript *> *, std::__1::hash<std::__1::basic_string >, std::__1::equal_to<std::__1::basic_string >, std::__1::allocator<std::__1::pair<const std::__1::basic_string, JS::PersistentRooted<JSScript *> *> > > &’ for 1st argument; dereference the argument with *
unordered_map(const unordered_map& __u);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/include/c++/v1/unordered_map:826:5: note: candidate constructor not viable: no known conversion from ‘std::unordered_map<std::string, JS::PersistentRootedScript *> *’ (aka ‘unordered_map<basic_string<char, char_traits, allocator >, PersistentRooted<JSScript *> *> *’) to ‘std::__1::unordered_map<std::__1::basic_string, JS::PersistentRooted<JSScript *> *, std::__1::hash<std::__1::basic_string >, std::__1::equal_to<std::__1::basic_string >, std::__1::allocator<std::__1::pair<const std::__1::basic_string, JS::PersistentRooted<JSScript *> *> > > &&’ for 1st argument
unordered_map(unordered_map&& __u)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/include/c++/v1/unordered_map:831:5: note: candidate constructor not viable: no known conversion from ‘std::unordered_map<std::string, JS::PersistentRootedScript *> *’ (aka ‘unordered_map<basic_string<char, char_traits, allocator >, PersistentRooted<JSScript *> *> *’) to ‘initializer_list<value_type>’ (aka ‘initializer_list<pair<const std::__1::basic_string, JS::PersistentRooted<JSScript *> *> >’) for 1st argument
unordered_map(initializer_list<value_type> __il);
^
1 error generated.

** BUILD FAILED **

The following build commands failed:
CompileC build/simulator.build/Debug/Simulator\ Mac.build/Objects-normal/x86_64/RuntimeJsImpl.o /Users/moonwalker/Desktop/dkd_dig/cocos2d-x-lite/tools/simulator/frameworks/runtime-src/Classes/ide-support/RuntimeJsImpl.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)

编译失败:请从上面的输出中查看错误细节

关闭时闪退还有一个

Simulator 编译确实有问题,感谢反馈

关闭时 websocket 退出的问题我再看一下,跟之前提交的一部分新代码有关系

websocket 退出崩溃的问题已经解决了

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

1赞

这个pr有提到2d-x吗?