崩溃
Bugly专业版提供全面的崩溃分析能力,支持Android与iOS多种崩溃异常的收集与上报,帮助用户更好地解决应用的质量问题。本文主要介绍Bugly专业版崩溃分析中,各模块的功能详情和使用方式。
崩溃概览
在崩溃概览页面,Bugly专业版提供崩溃率、崩溃趋势的全面分析,主要支持以下分析能力:
- 支持今日设备崩溃率、次数崩溃率、发生次数、影响设备数的展示,支持相对前一天的日环比对比。
- 支持多维度展示崩溃趋势,可以在 时间范围 处选择按5分钟聚合、1小时聚合或按天聚合,同时可以在右侧TAB栏中切换设备崩溃率、次数崩溃率、发生次数、影响设备数、联网设备数的展示。
- 支持版本对比功能,点击 版本对比 按钮可以选择不同的应用版本在趋势展示中进行比较。
- 支持趋势图时间范围内崩溃 Top问题分析 ,在趋势统计图中,可以点击曲线中不同的数据范围可以在下方展示该范围内的Top 3问题及影响范围。
- 支持统计不同应用版本、系统版本、机型的崩溃率下钻,点击右上角选择框可切换影响设备数或联网设备数。
- 支持统计展示指定日期下的Top 20崩溃问题,并统计了问题的影响面及波动情况。
个例筛选
在崩溃的问题列表中,Bugly专业版支持全方位的个例筛选能力,主要如下:
- 支持通过时间范围、APP版本、用户ID、设备ID、前后台状态、Issue类型等多维度字段的下钻搜索。
- 支持出错堆栈的高级搜索功能,支持分词与不分词,字段交集、并集或模糊匹配搜索。
- 支持业务设置处理状态、处理人、标签、标签颜色等自定问题类型的搜索。
- 支持业务上报 自定义字段 的搜索。
- 支持在Issue个例详情内根据 附件名称 搜索,可以筛选出有对应附件上报的个例。
其中,在问题列表的筛选界面中,支持条件对比功能。
条件对比分为A和B两种条件,可以分别对A和B的条件进行筛选过滤。如想分析相同版本不同时间的Issue问题变化情况,可以仅设置不同的时间范围,并选择相同的应用版本。如想分析相同时间,不同版本的的Issue问题情况对比,可以仅设置不同的应用版本,时间范围等条件相同。诸如此类设置,对比状态 可以选择所有、遗留、新增等状态,分别筛选过滤不同状态的问题。对比模式 也可以选择全量数据或Top数据。在选择完对比条件后,点击 查询 后开始对比。
条件对比结果会展示Issue问题的对比状态,并区分条件A和条件B下的上报次数,并分析两个条件下上报次数的变化情况。利用条件对比功能,可以快速了解崩溃或ANR等Issue问题的变化趋势。
下钻分析
在崩溃的Issue个例中,可以点击 下钻分析 切换到Issue问题的下钻分析界面。
下钻分析的 数据概览 部份,Bugly专业版提供崩溃Issue的发生次数、影响用户数、影响设备数、首次上报时间、最近一次上报时间等纬度的数据以供分析。在上报趋势部份,提供Issue问题按不同粒度的上报趋势统计图,粒度可以选择天、小时、分钟、5分钟,上报趋势可选择发生次数、影响用户数、影响设备数。
下钻分析的 统计分布 支持根据不同的维度(如应用版本、系统版本、机型等)以饼状图的形式分析Issue问题,分析同样支持发生次数、影响用户数、影响设备数的选择。如需要分析在该Issue问题下,不同机型、架构的分布比例;或分析不同的应用版本中出现该问题的比例,可以使用该统计分布功能进行查看。
下钻分析的 出错堆栈分析 支持按出错堆栈的内容进行分析问题,点击右上角的 编辑条件 可以添加编辑条件,在编辑条件中支持添加需搜索的字符串,如搜索 com
字符在当前Issue问题中出现的个例数量。搜索后的个例数量以柱状图的方式提供对比展示。
以下功能介绍区分 Android 平台与 iOS 平台。可通过TAB切换不同平台的功能介绍。
- Android
- iOS
出错堆栈
出错堆栈详细展示当前崩溃问题堆栈,是分析解决崩溃问题最直接的信息。
在Java崩溃堆栈中,出错堆栈展示的是error message和当前出错调用栈,调用栈通常由文件名+符号+偏移组成。如果Java代码在编译时配置了混淆,可以通过上传混淆的mapping符号表来翻译混淆后的符号。如果已上传符号表,可以通过右边按钮来切换展示原始堆栈或还原后堆栈,默认展示还原后堆栈。
如当前线程堆栈无法定位问题,可以点击 展开其他线程堆栈 来查看其他线程堆栈,其他线程堆栈同样支持符号的还原。
在Native崩溃堆栈中,出错堆栈展示的是错误信号名和当前出错调用栈,原始的调用栈通常由地址偏移+可执行文件名+符号+偏移+可执行文件架构及UUID组成,还原后的堆栈由地址偏移+符号+偏移组成,如下图所示。解决Native崩溃问题时,通常先找到业务堆栈对应的出错符号,并根据还原后的符号找到对应的代码行进行自查。如果堆栈中不存在业务堆栈,则可能需要多走查相关问题,并借助其他信息(如日志、进程信息等)进行辅助分析定位问题。
在出错堆栈中,如果未上传堆栈对应符号表,页面会提示堆栈未翻译,可以点击 去上传 跳转至符号表上传界面。上传完符号表后,点击页面右上方 手工还原 按钮,等待数分钟后刷新页面,堆栈即可被还原,操作流程可参考 符号表FAQ。
现场数据
现场数据是崩溃发生时采集的现场数据信息,主要包含三个部份。
第一部份基础数据包括网络APN、内存状态、存储状态、JVM状态等,其中 JVM最大内存
表示JVM可以使用最大堆内存大小,JVM已分配内存
表示JVM已分配的内存大小,通过情况下,已分配内存的值会小于最大内存值,当Java程序需要更多内存时,JVM会自动扩展堆内存大小,直到达到最大内存为止,如果JVM无法分配更多内存,就可能会抛出OutOfMemoryError异常。JavaHeap
表示分配的内存中,存储Java对象实例使用的内存大小,PSS
表示进程共享内存的大小,VSS
表示进程虚拟内存的大小。
第二部分自定义字段展示用户通过接口上传的自定义字段,可参阅 自定义数据。
第三部份页面跟踪展示崩溃前页面的生命周期跟踪,可以分析用户发生崩溃前,进行了哪些页面操作。
日志
日志部份展示了崩溃发生时间前后的日志流,支持通过日志级别、关键字对日志进行检索。
FD信息
FD信息展示了崩溃发生时的FD使用状态。
包括当前已使用的FD数、当前未使用的FD数和单进程最大可使用的FD数。并按照FD的类型、数量,占比进行分类。在FD详情中,展示了具体被打开的FD资源路径,并在尾部标识了有多少个FD指向该路径。可以使用FD信息来辅助排查问题,了解在崩溃发生时,哪种类型的FD打开过多。或可以针对打开过多的FD类型进行优化。
进程信息
Native崩溃上报该信息,Java崩溃不上报。
进程信息展示了崩溃发生时与进程相关的信息,包括Maps信息,Meminfo信息、进程状态和线程状态。进程信息的原始内容可以在附件 state_file.zip 中查看。
Maps信息是用户进程运行时的内存映像,能够查看到当前进程空间的映射情况。可以通过地址、内存段名、访问权限来过滤筛选指定的内存段。其中内存段的筛选支持正则表达式匹配,访问权限需全匹配,如可读可写可执行的私有内存段表示为rwxp。
Meminfo信息表示了用户进程的内存使用情况,可以查看应用当前内存主要被如何分配。
在Meminfo信息的横坐标中,Native Heap
和 Dalvik Heap
分别表示本地堆和Dalvik堆的使用情况,Dalvik Other
表示Dalvik堆之外的内存使用情况。Stack
表示进程堆栈的使用情况,Ashmem
表示匿名共享内存的使用情况。Other dev
表示其他设备内存的使用情况。.so mmap
、.jar mmap
、.apk mmap
、.ttf mmap
、.dex mmap
、.art mmap
、.oat mmap
分别表示共享库、JAR文件、APK文件、字体文件、DEX文件、ART文件、OAT文件的内存使用情况。Other mmap
表示其他内存映射文件的使用情况,GL mtrack
表示OpenGL ES内存使用情况 Unknow
表示未知的内存使用情况。
在Meminfo信息的纵坐标中,Pss Total
表示进程使用的总共物理内存大小,包括共享库、匿名共享内存和堆栈等。Private Dirty
表示进程使用的私有脏内存大小,即进程独占的内存大小,包括堆、栈、匿名共享内存等。Private Clean
表示进程使用的私有干净内存大小,即已被清理不包含任何数据的内存。SwapPss Dirty
表示进程的交换的内存脏页大小。
进程状态和线程状态分别表示当前运行进程及其中各线程的状态指标。在线程状态中,可以点击线程名称旁边的箭头展开单个线程的状态,鼠标hover至对应指标时,会展示对应状态指标的含义。
符号表
在崩溃个例的消息详情中,也可以进行符号表的上传。区别于 设置 中的符号表上传,这里仅展示在当前个例的 出错堆栈 中未被还原的Java堆栈和Native堆栈所需的对应符号表。
其中,Java符号表文件根据版本号+构建号进行匹配,so符号表文件根据UUID进行匹配,点击 待上传,点击上传 按钮可在该页面上直接上传对应符号表,上传完成后需点击 手工还原 按钮进行还原操作,等待数分钟后即可翻译当前 出错堆栈 ,符号表相关参阅 符号表。
附件
Bugly专业版支持所有附件的打包下载。对于用户自定义上报的数据文件,可以在以下附件中找到:
- 通过回调接口
Bugly.getCrashExtraData
设置的内容存放在userExtraByteData中。 - 通过回调接口
Bugly.getCrashExtraMessage
设置的内容存放在user_datas.log附件中。 - 通过自定义字段
Bugly.putUserData
设置的内容会放在valueMapOthers.txt中。 - 通过自定义文件
Bugly.setAdditionalAttachmentPaths
设置的大文件会放在custom_log.zip中。
FAQ
1.为什么本地崩溃没有上报?如何进行排查?
首先确认Bugly本地已被正确初始化,在初始化时将Bugly的debug模式 builder.debugMode
设置为true,在adb调试中使用 logcat -s CrashReport eup
命令过滤日志,可以看到Bugly专业版有如下打印,则表明Bugly本地已被正确初始化。
06-13 11:03:09.597 27513 27513 W eup : Bugly debug模式开启,请在发布时把isDebug关闭。 -- Running in debug model for 'isDebug' is enabled. Please disable it when you release.
06-13 11:03:09.597 27513 27513 E eup : --------------------------------------------------------------------------------------------
06-13 11:03:09.597 27513 27513 W eup : Bugly debug模式将有以下行为特性 -- The following list shows the behaviour of debug model:
06-13 11:03:09.597 27513 27513 W eup : [1] 输出详细的Bugly SDK的Log -- More detailed log of Bugly SDK will be output to logcat;
06-13 11:03:09.597 27513 27513 W eup : [2] 每一条Crash都会被立即上报 -- Every crash caught by Bugly will be uploaded immediately.
06-13 11:03:09.597 27513 27513 W eup : [3] 自定义日志将会在Logcat中输出 -- Custom log will be output to logcat.
06-13 11:03:09.597 27513 27513 E eup : --------------------------------------------------------------------------------------------
其次确认异常是否能被Bugly正常捕获。在触发崩溃或ANR问题后,应有以下日志打印,表明崩溃异常可以正常被Bugly捕获。
06-13 11:11:41.777 29271 30104 E eup : #++++++++++Record By Bugly++++++++++#
06-13 11:11:41.777 29271 30104 E eup : # You can use Bugly(http:\\bugly.qq.com) to get more Crash Detail!
06-13 11:11:41.777 29271 30104 E eup : # PKG NAME: com.tencent.demo.buglyprodemo
06-13 11:11:41.777 29271 30104 E eup : # APP VER: 1.0.0
06-13 11:11:41.777 29271 30104 E eup : # SDK VER: 4.3.0.30-SNAPSHOT
06-13 11:11:41.778 29271 30104 E eup : # LAUNCH TIME: 2023-06-13 11:09:41
06-13 11:11:41.778 29271 30104 E eup : # CRASH TYPE: JAVA_CRASH
06-13 11:11:41.778 29271 30104 E eup : # CRASH TIME: 2023-06-13 11:11:41
06-13 11:11:41.778 29271 30104 E eup : # CRASH PROCESS: com.tencent.demo.buglyprodemo
06-13 11:11:41.778 29271 30104 D eup : isAppForeground:true
06-13 11:11:41.778 29271 30104 E eup : # CRASH FOREGROUND: true
06-13 11:11:41.778 29271 30104 E eup : # CRASH THREAD: Thread-9
06-13 11:11:41.778 29271 30104 E eup : # REPORT ID: cf5fb020-4c42-4cee-8d78-299940bd4d56
06-13 11:11:41.779 29271 30104 E eup : # CRASH DEVICE: V2034A UNROOT
06-13 11:11:41.780 29271 30104 E eup : # RUNTIME AVAIL RAM:5672812544 ROM:87523766272 SD:87314046976
06-13 11:11:41.780 29271 30104 E eup : # RUNTIME TOTAL RAM:8068177920 ROM:116628795392 SD:116419080192
06-13 11:11:41.780 29271 30104 E eup : # CRASH STACK:
06-13 11:11:41.780 29271 30104 E eup : java.lang.RuntimeException: This Crash create for Test! You can go to Bugly see more detail!
06-13 11:11:41.780 29271 30104 E eup : at com.tencent.bugly.proguard.dz.dq(Unknown Source:16)
06-13 11:11:41.780 29271 30104 E eup : at com.tencent.bugly.library.Bugly.testCrash(Unknown Source:28)
06-13 11:11:41.780 29271 30104 E eup : at com.tencent.demo.buglyprodemo.MainActivity$2$1.run(MainActivity.java:85)
06-13 11:11:41.780 29271 30104 E eup : at java.lang.Thread.run(Thread.java:919)
06-13 11:11:41.780 29271 30104 E eup : #++++++++++++++++++++++++++++++++++++++++++#
最后检查异常是否能正常上报。可以在上述过滤的日志中检索 crash upload
关键字,会有如下崩溃类型+上报是否成功的打印。如上报成功,会有如下打印示例。如上报不成功,可联系Bugly小助手咨询原因。
06-13 11:25:44.752 1566 1795 I eup : java.lang.RuntimeException, crash upload success!
其他问题原因分析:
- 上报可能存在一定延时,如确认上述上报成功的日志已经打印,可以等待数分钟后刷新页面看是否已经上报。
- 如遇Bugly无法正常捕获崩溃异常的情况,可以检查当前业务中是否有其他逻辑注册了异常捕获函数或信号,或是有集成其他第三方异常捕获SDK。建议仅在业务中集成一项异常捕获SDK,其他SDK捕获逻辑可能会对Bugly的异常捕获存在干扰。
2.为什么有的信息(如进程信息)没有数据展示?
进程信息: Java崩溃不上报进程信息。如是Native崩溃或ANR问题,进程信息的上报链路不跟随崩溃上报,用户在发生崩溃问题后,需再次启动APP,才会上报进行信息,并自动关联至对应异常个例。如遇进程信息栏目未展示,可能是用户未二次启动APP。
Native崩溃的部份现场数据: 在发生Native崩溃时,如JVM相关的现场数据无法获取,原因可能是JVM环境可能已被破坏,崩溃处理逻辑无法进入Java层进行采集。
其他信息: 与崩溃捕获处理链有关,可能是系统逻辑中断了处理导致信息未采集完成。详情可咨询Bugly小助手。
4.为什么相同的崩溃问题没有被聚在同一个Issue里?
Bugly专业版会提取崩溃问题 出错堆栈 中的部份栈帧作为特征进行聚合,在 问题详情 的顶部展示了提取的堆栈特征。主观认为相同的堆栈,未被聚合在同一个Issue中,是因为堆栈之间存在差异导致提取的特征之间存在差异。
如认为提取的堆栈特征不够合理,可以联系Bugly小助手进行咨询与反馈。
5.为什么联网设备数的波动较大?崩溃率的波动较大?
联网设备数的统计是根据设备ID进行统计的,不正确地设置设备ID(uniqueId)会导致联网设备数统计异常,如不能将不同设备的设备ID设置为相同值或固定值。联网设备数波动可能受此影响。
崩溃率的波动可能会受联网设备数的影响。如联网设备数趋于稳定,而崩溃率波动较大,则需根据具体业务逻辑进行排查。
6.如何判断崩溃问题上报的Bugly SDK版本?
可以先通过筛选条件过滤APP版本,找到当前APP版本的一条上报个例,在上报个例的现场数据中,可以找到 Bugly SDK版本号 字段,即可知道当前集成的Bugly SDK版本号。
7.为什么上报的堆栈提示未翻译?
如在 出错堆栈 中提示堆栈未翻译,可以先进行如下自查:
- 对应的符号表是否已经上传,Java mapping符号表使用版本号+构建号进行匹配,Native so符号表使用UUID进行匹配。
- 如果是Native堆栈,需检查上传的Native so是否是被裁剪过的so,裁剪过的so不携带符号表,无法进行翻译。可以使用
file
命令查看so是否被裁剪,本地执行file libxxx.so
来打印so相关信息。not stripped是未裁剪过的so,stripped是裁剪过的so。 - 如仍不能解决问题,可参阅 符号表FAQ。
出错堆栈
出错堆栈详细展示当前崩溃问题堆栈,是分析解决崩溃问题最直接的信息。
在iOS崩溃堆栈中,出错堆栈展示的是Crash reason和Crash线程堆栈.堆栈主要由以下几个模块组成:行号、模块名、指令地址、基地址、地址偏移。翻译后的堆栈主要有以下几部分组成:行号、模块名、函数名、行号。