# Crasheye 常见问题
# Android
# Q: 符号文件什么时候生成?
A:每编译一次就会生成全新的符号文件,Android平台中,目标文件对应的是SO文件。每次构建或者发布APP版本的时候,一定要做好 备份好符号文件,或 做符号文件自动上传。自动上传方法可查看Q3
# Q: 符号文件路径位置?
A:通常游戏项目,需要上传项目编译的so (如果有c++代码,也需要上传c++ 编译的so),以及libunity.so
工程中,有xx.sym.so 或 xxx.dbg.so 或 xxx.so 这几种符号文件 uuid是相同的,通常推荐上传xxx.dbg.so
符号文件的位置通常在:
il2cpp
- libunity.so (如果没有重新编译引擎,默认在编辑器的如下目录)
- libil2cpp.so (打包后在项目自己的构建临时目录下)
il2cpp Release(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\armeabi-v7a\libunity.sym.so
il2cpp Development(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Symbols\x86\libunity.sym.so
il2cpp Release(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\x86\libunity.sym.so
il2cpp Development(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Symbols\x86\libunity.sym.so
MONO
mono需要上传的符号文件
- libunity.so (如果没有重新编译引擎,默认在编辑器的如下目录)
- libmono.so (如果没有重现编辑mono,默认在编辑器的如下目录)
Release(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Symbols\armeabi-v7a\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\MonoLibs\armeabi-v7a\libmono.so
Release(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Symbols\x86\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\MonoLibs\x86\libmono.so
Development(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Symbols\armeabi-v7a\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\MonoLibs\armeabi-v7a\libmono.so
Development(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Symbols\x86\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\MonoLibs\x86\libmono.so
注意!!!
- 如果勾选了 strip engine code, 必须要勾选Creat Symbol.zip , 项目打包出来以后会生成符号zip和libunity.so,否则将没有符号文件生成!!!
# Q: 符号文件每次都要上传吗?怎么做自动上传
A:为了方便找回Crash对应的Debug SO文件和还原堆栈,每次构建或者发布APP版本的时候,一定要做好 备份好符号文件,或 做符号文件自动上传。一旦符号文件无法找回,堆栈将无法还原!!!
符号文件自动上传方法:
- 构建脚本使用符号文件工具进行上传
使用符号文件工具,在构建脚本中进行上传
注意!!!
上传xx.sym.so 或 xxx.dbg.so 的时候!!!必须!!!重命名,重命名规则:xxx.sym.so->xxx.so, xxx.dbg.so->xxx.so 然后再上传。(不重命名再跑命令行,分析后台会无法匹配到符号)
如果勾选了 strip engine code, 必须要勾选Creat Symbol.zip , 项目打包出来以后会生成符号zip和libunity.so,否则将没有符号文件生成!!!
# Q: 平台显示符号文件uuid比本地符号文件uuid多了一个0,是为什么?
A: Crasheye 里面uuid计算方式和buildid是有些区别的,最后一位都会加一个0,不影响符号文件匹配
# Q: 符号文件的uuid 是什么?
A:elf文件的build id,每次编译生成唯一ID
# Q: 调用了log接口,但是没有收集上log
A: manifest中是否有 READ_LOGS 权限
# Q: Android 触发dump 后,为什么收不到崩溃?
A:按照下述步骤进行排查
- 查看日志,确认Crasheye init 成功
- 触发崩溃后,是否重启游戏,dump 将在重新启动游戏后上报,通常10min内就会上报
- 确认android 初始化是否在java 层,打java包的方法,详见Android初始化
# Q: 后台只看到Java相关的错误堆栈信息,没发现有NDK相关的堆栈异常?
A: 问题排除方法:
这种情况应该是初始化错误,Crasheye NDK相关的初始化应该是调用:详情参考Android NDK接入指南
Crasheye.initWithNativeHandle(this, "Your_Appkey");
不同的项目引擎排除方法也不一样,Logcat中有相应的日志输出,例如:引擎使用Cocos2d,查看logcat初始化日志:
查看是否有以上的NDK初始化信息,如果没有,代表NDK没有初始化成功,请参照第一步重新初始化;
3. 请不要将Crasheye加入代码混淆;
4. 如果是项目的so也加入了混淆,则Crasheye无法捕获NDK的宕机;
# Q: 部分机型在Android5.0 之后的版本捕获不到NDK异常?
A: libCrasheyeNDK.so 版本过旧,更新官网最新版本的so就可以成功捕获;(NDK下载)
# Q: 接入Unity SDK后,初始化提示 mono signal chain fail 是啥原因?
A: 该Error并不影响Crasheye 的接入,忽略即可
# Q: 页面堆栈未解析,是什么原因?
A: 请根据下述方法进行排查
符号文件没有上传
页面提示 module “符号文件名” uuid “符号文件uuid” is miss
- 点击重新分析,如果页面仍然进行 miss提示,进行步骤2排查
- 在设置 - 符号文件 页面,根据uuid,搜索符号文件是否存在,符号文件名 是否完全匹配
- 如果符号文件不存在,请在构建机上查找符号文件并重新上传
- 堆栈损坏
页面提示 module “符号文件名” uuid “符号文件uuid” is corrupt,底层breakpad 无法解析,此种崩溃无论是Crasheye 还是用户都无法进行任何处理,通常这种崩溃仍然可以解析出部分堆栈,用户可以根据有限的堆栈,进行崩溃分析。更多的解释可见:
Heap corruption occurs when dynamic allocation of memory is not handled properly. Typical heap corruption problems are reading, or writing outside of the bounds of allocated memory, or double-freeing memory. Since the result (e.g. a hard crash) can happen later, when the program tries to manipulate the incorrectly allocated piece of memory, the root cause of the issue can remain hidden from your eyes.
- 先触发崩溃,再上传崩溃,点击重新分析即可
服务不会实施监控符号文件上传,因此先触发崩溃,再上传崩溃,页面堆栈也会未解析,此时需要点击重新分析,堆栈将会重新解析
# Q: 如何获取lua 的脚本异常?
A:在初始化后调用API,捕获到脚本异常(例如空指针等),Android、iOS、Unity 插件均支持捕获脚本异常,具体接入见常用API
为了减少重复上报,相同的异常信息在 10 分钟内只能上报一次
# Q: 堆栈解析可以定位到行号吗?
A: 有些可以定位到行号,有些不行。
不是所有的堆栈都可以解析出行号的,需要具体问题具体分析。
如果已经上传符号文件,并且已经点击重新分析,可以查看解析后的堆栈
# iOS
# Q: 什么是dSYM文件?
A: iOS中,dSYM文件是指具有调试信息的目标文件,文件名通常为: xxx.app.dSYM
一般情况下,项目编译完dSYM文件跟app文件在同一个目录下
XCode -> 项目工程 -> Products -> XXX.app -> 右键"显示文件夹" -> XXX.app.dSYM
为了保证能够还原堆栈信息, 建议每次构建或者发布版本时候,备份好dSYM文件 。
# Q: 符号文件工具上传报错 dump_syms command is exception
,怎么解决?
A: dump_syms没有访问权限,要执行以下chmod a+x dump_syms
的这个可执行文件。
# Q: 接入Crasheye后app启动崩溃,Log里有输出 <Error>: +[NSString ksgIsNilOrEmpty:]: unrecognized selector?
A: Linker Flags中没有添加-ObjC选项;(详情参考:iOS SDK接入指南)
# Q: 生成的crash 文件存储在什么位置?
A: 保存在Library/Caches/Crasheye
下
# Q: 产生崩溃后,为什么没有生成对应的crash文件?
A: 1.检查log,查看Crasheye是否有正常初始;
2.检查是否连接debugger,连接debugger时,不生成crash文件;
# Q: 产生崩溃后,网站上为什么没有对应记录?
A: 重新启动App才会上传上一次崩溃的crash文件。
# Q: iOS 触发dump 后,为什么收不到崩溃?
A:按照下述步骤进行排查
- 查看日志,确认Crasheye init 成功
- Crasheye不收集杀端 sigkill 、内存宕机、无限递归宕机,如果宕机类型为这几种,将不会上报
- 触发崩溃后,是否重启游戏,dump 将在重新启动游戏后上报,通常10min内就会上报
- 确认是否在调试状态下,调试状态下不捕捉dump, 测试的时候不要接调试器(xcode
# Unity
# Q: Unity工程符号文件在哪里?
MONO
mono需要上传的符号文件
- libunity.so (如果没有重新编译引擎,默认在编辑器的如下目录)
- libmono.so (如果没有重现编辑mono,默认在编辑器的如下目录)
Release(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Symbols\armeabi-v7a\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\MonoLibs\armeabi-v7a\libmono.so
Release(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Symbols\x86\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\MonoLibs\x86\libmono.so
Development(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Symbols\armeabi-v7a\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\MonoLibs\armeabi-v7a\libmono.so
Development(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Symbols\x86\libunity.sym.so
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\MonoLibs\x86\libmono.so
il2cpp
il2cpp需要上传的符号文件
- libunity.so (如果没有重新编译引擎,默认在编辑器的如下目录)
- libil2cpp.so (打包后在项目自己的构建临时目录下)
il2cpp Release(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\armeabi-v7a\libunity.sym.so
il2cpp Development(armeabi-v7a)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Symbols\x86\libunity.sym.so
il2cpp Release(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\x86\libunity.sym.so
il2cpp Development(x86)版本
\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Symbols\x86\libunity.sym.so
如果勾了这个striped,那么需要在打包的时候勾上create symbols.zip,里面才会有符号文件,不能再去引擎目录拿了, striped过后的so连buildid都变了。
其他第三方库符号文件根据应用需求上传即可
# Q: Unity捕获不到脚本异常信息?
A: 问题排除方法:
- 应用程序在最外层添加了try catch,导致异常被try catch捕获,没有被Crasheye捕获到;
- 搜索项目其他地方有无重复使用 Application.RegisterLogCallback,如果有请使用Crasheye.SetRegisterLogFunction 代替,详情查看 帮助文档 ;
- 确定Crasheye.cs 在项目启动入口有初始化;
# Q: Unity使用MONO接入的好处是什么?
A: 使用unity接入后可以查看到部分NDK崩溃的C#的堆栈信息,如下图
# Q: Unity如何查看NDK堆栈信息?
A: 把unity版本下的libmain.so、libunity.so、libmono.so
符号文件上传到Crasheye服务,Crasheye会自动进行重新分析,稍等片刻即可查看到相关的NDK堆栈信息;
# 符号文件
# Q: 什么是符号表,配置符号表的作用是什么?
A: 符号表是内存地址与函数名、文件名、行号的映射表。为了能快速并准确地定位用户APP发生Crash的代码位置,Crasheye使用符号表对APP发生Crash的程序堆栈进行解析和还原
# Q: 配置符号表是不是必须的?什么情况下必须配置符号表?
A: 不是必须的,不会影响异常上报,但建议您进行配置。
# Q: 符号文件上传提示成功,但崩溃堆栈信息仍未分析出详细结果
A: 确认所上传的符号文件版本是否正确(方法是:刷新崩溃详情页,在页面头部显示的提示信息中的uuid是否在“设置 – 符号文件 – 符号文件上传 - 已上传列表”中存在)
# Q: 符号文件上传是否有文件大小限制?
A: 使用工具上传时,单文件最大1G,其他方式上传无限制,请放心使用
# Q: iOS 上传文件提示 run lipo -info false?
A: 问题排除方法:
- 是否使用了正确的符号文件上传工具,iOS应用的符号文件上传工具文件名为***iOS***.jar,Android应用的符号文件上传工具文件名为***Android***.jar;
- 符号文件路径不支持空格,若有,请将空格删除;
# Crasheye 后台使用
# Q: 如何添加成员?
A: 第一步:在Crasheye平台鼠标移入左边菜单栏选择权限管理平台 (opens new window)
第二步:切换成员管理,点击新增,通过Email进行搜索项目成员并选择用户组信息,Email以英文逗号隔开可同时添加多个成员,点击保存即添加成功
非管理员权限,无法添加成员,可咨询对应项目的管理员,进行添加
# Q: 如何创建AppKey?
A:第一步:在Crasheye平台鼠标移入左边菜单栏选择权限管理平台 (opens new window)
第二步:切换至项目信息,点击新增,填写应用名称(通常建议填写地区)、选择平台,确定后系统自动生成AppKey
# Q: 如何进行告警?
A: 在Crasheye 平台 (opens new window) 设置 - 监控设置 - 告警设置 点击添加告警规则
满足告警规则后,App的使用次数必须> 0 ,才能触发告警,项目将(以AppKey 作为唯一标识)从此刻开始24小时内(崩溃数、崩溃率、受影响用户数、受影响用户率),发送告警邮件,邮件无上限。
同一个崩溃问题:
首次触发告警,大约在10min - 30min 内收到告警邮件;
再次达到告警阈值(与上一次作比较数值不变,不触发告)隔1个小时后发送第2封邮件;
服务每10min左右校验一次告警规则,邮件服务接收告警失败,每0.5min重试1次,重试失败抛异常,达到3次停止重试,结果记录日志。
监控项
指定版本: 指定一个版本号并且该版本号上报崩溃触发告警规则;指定多个版本号时,任一版本满足告警规则,触发告警。
所有版: 所有版本满足告警规则,触发告警。
单个版本: 任一版本满足告警规则,触发告警。
单个崩溃问题: 当某个崩溃问题,崩溃数超过x时候,触发告警
监控指标
崩溃率 (推荐): 崩溃率 (%)=崩溃次数/ 使用次数,保留1位小数点
受影响用户率(推荐): 受影响用户率(%) = 受影响用户数/ 用户数,保留1位小数点
崩溃数: 使用App 发生的闪退数量,整数
受影响用户数: 一台设备发生多次闪退,计做一个受影响用户数,整数
# Q: 如何升级Crasheye后台?
为了进一步提高用户体验,系统服务性能,Crasheye 后台将升级至新版,旧数据不会收到影响 旧版同时会停止权限管理的入口
注意:仅管理员权限才能进行升级
提交后,项目将完成升级
# Q: Crasheye是否收费?
A: 永久免费,请放心使用
# Q: Crasheye是否会有数据泄漏问题?收集了哪些信息?
A: 所收集的数据都是与崩溃相关,目的是为了给开发者提供真实的崩溃场景,并未收集任何个人隐私信息,且数据分析完成后,只针对该项目成员开放
常规收集的信息主要包括:
崩溃环境:Crash信息及线程堆栈,ROM/RAM、网络环境/系统语言等
App信息:包名、版本、所属进程名
设备信息:设备名称、系统版本、屏幕分辨率
开发者均可以通过打印上报数据日志来查看所有上报内容
# Q: 未上线的应用可以使用吗?
A: 可以
# Q: Crasheye和第三方SDK同时编译会不会有冲突?
A: 可能会有冲突,接入时遇到问题可联系Crasheye或第三方SDK的官方人员,或在相应帮助中查找解决方案
# Q: Crasheye和同类SDK同时使用会不会有冲突?
A: 不会,建议将Crasheye在同类SDK初始化之后再初始化
# Q: 接入Crasheye后会不会影响程序的运行速度?
A: 几乎没有影响,Crasheye只会在应用启动的时候,检查上次是否有崩溃数据需要上传,若有,则数据经过压缩后再上传,不影响应用的功能
# Q: 消耗的流量大不大?
A: Crasheye提供接口设置只在wifi环境下才上报,当不在wifi下产生的宕机文件会保存到本地,等wifi环境下再上传,据Crasheye的统计,平均每个崩溃的数据传输量在10K左右
# Q: (iOS)接入Crasheye会影响app store发布吗?
A: 不会
# Q: Crasheye支持哪些自定义的功能?
A: 提供了多个功能控制接口和信息记录API:
# Q: 我现在使用我自己的账号登录,由于工作变动可以把登录账号更改了吗?
A: 如果你是“应用所有者”,无法将帐号和应用进行解绑,建议在创建应用时使用公司产品邮箱,而非个人名字邮箱 如果你非“应用所有者”,联系“应用所有者”进行解除关联即可
# Q: 接入Crasheye之后,对原应用的内存占用和CPU消耗会有多大影响?
A: 接入Crasheye之后,内存占用增加了0.86MB,CPU峰值均为1%,并无影响。
测试方法:使用 TestPlus客户端 (opens new window) 性能测试工具,对同一程序在接入Crasheye前后均至少测试三次,每次测试时间不少于30秒,取平均值。
测试数据见下表:
无Crasheye | 有Crasheye | 增幅 | |
---|---|---|---|
内存 | 32.81MB | 33.67MB | 0.86MB |
CPU峰值 | 1% | 1% | 0% |
测试手机:红米note3
# Q: 项目已经接入了Crasheye,但页面显示未接入?
A: 问题排除方法:
Step1:访问网络权限是否已经添加;
< uses-permission android:name="android.permission.INTERNET"/>
Step2:在logcat搜索是否有以下字符(上报活跃);
NetSender: Sending data to url: http://rp.crasheye.cn/session (opens new window)
Step3:查看是否有以下结果;
NetSender: Transmitting result {"ret":0,"msg":"","data":{"appkeyvalid":true}}
若以上3步检查不通过,请查看帮忙文档重新接入或者联系官方工作人员
# Q: 为什么我的应用崩溃率会超过100%?
A: 有以下两种可能:
应用一启动就产生了崩溃,并成功被Crasheye捕获到,但是,报活未完成,由于崩溃堆栈有上报失败缓存功能,而报活无此逻辑,导致在之后的某次上报中,同时上报了多条崩溃,但只有一次报活,在这种情况下,可能会出现崩溃次数大于报活的情况,就终会导致崩溃率会超过100%;
应用在服务(service)里初始化了Crasheye,服务在产生崩溃之后,Crasheye会将该崩溃上报,但由于服务启动时是不会进行session(报活),而主程序此时并未崩溃,如果大量出现这种(服务崩溃的)情况就会导致 崩溃数 > 报活数;如果确定需要在服务里收集崩溃,崩溃数大于报活数的现象是属于正常的;
ps:Crasheye为什么不对服务进行报活?服务的崩溃,是不会对主程序功能产生影响的,并且主程序可以随时把服务启动起来,但服务的启动不能算是一次用户的活跃,所以Crasheye才确定不在服务里提供报活。
# Q: 如何通过发生宕机的手机,在页面上查找到对应的宕机信息?
A: 有两种方法可以定位到宕机问题:
方法一:通过uid 可以定位到此机器的所有宕机信息;
- 手机接入电脑,通过logcat可以查到uid的值,通过此值可以在电脑上查找,如下图的uid为:69d86f0988d898df246e36071bb02baa
- 通过设备ID可以直接在页面上进行搜索:
编号#950的宕机信息就是我们需要搜索的宕机。
方法二:通过用户标识定位宕机信息;
- 用户标识是在初始化Crasheye的时候设置进来: (可以查看常用API: 设置用户标识 )
- 假如你设置的用户标识为UserByCQF,那么在页面里就可以这么搜索:
页面就会把所有有关UserByCQF这位用户的所有宕机都会列出来。