关于cocos2d::FileUtilsAndroid::isFileExistInternal()调用AAssetManager_open方法 crash问题解决方案
cocos2d在华为平行视界中必现一个crash bug,
1
#00 pc 00054156 /apex/com.android.runtime/lib/bionic/libc.so (abort+165) [armeabi-v7a]
2
#01 pc 0009d403 /apex/com.android.runtime/lib/bionic/libc.so (__fortify_fatal(char const*, ...)+26) [armeabi-v7a]
3
#02 pc 0009cc0d /apex/com.android.runtime/lib/bionic/libc.so (HandleUsingDestroyedMutex(pthread_mutex_t*, char const*)+20) [armeabi-v7a]
4
#03 pc 0009caf9 /apex/com.android.runtime/lib/bionic/libc.so (pthread_mutex_lock+132) [armeabi-v7a]
5
#04 pc 00078f63 /system/lib/libc++.so (std::__1::mutex::lock()+2) [armeabi-v7a]
6
#05 pc 0000c04d /system/lib/libandroid.so (AAssetManager_open+36) [armeabi-v7a]
7
#06 pc 0074a5b7 /data/app/com.hhdd.kada-fPiuHXdy1A80T__Cb3T4sQ==/lib/arm/libMyGame.so (cocos2d::FileUtilsAndroid::isFileExistInternal(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) const+166) [armeabi-v7a]
8
#07 pc 009eb1ec /data/app/com.hhdd.kada-fPiuHXdy1A80T__Cb3T4sQ==/lib/arm/libMyGame.so (cocos2d::FileUtils::getFullPathForDirectoryAndFilename(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) const+292) [armeabi-v7a]
9
#08 pc 009e8f40 /data/app/com.hhdd.kada-fPiuHXdy1A80T__Cb3T4sQ==/lib/arm/libMyGame.so (cocos2d::FileUtils::getPathForFilename(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) const+924) [armeabi-v7a]
10
#09 pc 009e9218 /data/app/com.hhdd.kada-fPiuHXdy1A80T__Cb3T4sQ==/lib/arm/libMyGame.so (cocos2d::FileUtils::fullPathForFilename(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) const+424) [armeabi-v7a]
11
#10 pc 0076a848 /data/app/com.hhdd.kada-fPiuHXdy1A80T__Cb3T4sQ==/lib/arm/libMyGame.so (cocos2d::CSLoader::nodeWithFlatBuffersFile(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, std::__ndk1::function<void (cocos2d::Ref*)> const&)+64) [armeabi-v7a]
12
#11 pc 00766988 /data/app/com.hhdd.kada-fPiuHXdy1A80T__Cb3T4sQ==/lib/arm/libMyGame.so (cocos2d::CSLoader::createNodeWithFlatBuffersFile(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&)+52) [armeabi-v7a]
这个问题研究了一周时间,终于解决了;
简单描述一下问题,在原生app activity中新启动cocos2dActivtiy,此时在华为平行视界的设备上两个activtiy都会处于活跃状态,(华为这个技术还是很牛逼的),此时再跳转一个webView页面,关闭webView后,退出cocos2dActivtiy;再次打开cocos2dActivtiy就会crash;
问题最终crash在libc.so HandleUsingDestroyedMutex中,考虑可能重复释放线程锁导致crash,Android系统应该在找Assets下资源时启用的多线程在同时查找;
但是怎么会crash呢,要找的资源明明存在,而且并不是在用这个资源时崩溃了,而是判断这个资源是否存在时就崩掉了,百思不得其解,那就迂回战术,有什么办法规避一下,用xhook将pthread_mutex_lock 勾出来执行自己的方法,还是崩;
往下走是走不通了,那就再往上找AAssetManager_open,这个方法中就传了三个参数AAsset* aa = AAssetManager_open(FileUtilsAndroid::assetmanager, s, AASSET_MODE_UNKNOWN);
名字和类型很简单应该没问题,那问题就出在FileUtilsAndroid::assetmanager了,这又能有什么问题呢,这个不应该不会变的吗吗吗???
问题就出在这,通过打印指针地址发现它居然会变,居然会变,居然会变,但是cocos2dHelper中设置nativeSetContext只会初始化一次,再次进入cocos2dActivity中,还用之前的地址去找资源,必然会crash了,找到问题修改起来就简单了,
解决方法是每次启动cocos2dActivity都初始化一下nativeSetContext,就不会crash了。但是在平行视界中webView为什么会导致getAssets地址改变待研究(不知道是谁的锅)
                    
                
                
            
        
浙公网安备 33010602011771号