附件使用说明
附件是以文件形式提供的异常现场数据,包含了两种类型的数据:平台默认采集的数据和业务自定义采集的数据。
功能简介
在Bugly平台的个例详情中,「附件」Tab展示当前异常个例所有的附件,用户点击即可在线查看附件内容。用户也可以通过「打包下载」按钮,下载当前个例的所有附件。
批量导出
用户可以通过批量导出功能,导出一批个例的附件,如下图所示:
搜索附件
用户可以通过「附件」的筛选项,搜索出包含指定附件的个例。
当选择多个附件时,表示或关系,过滤出包含以下附件中任意一种附件的异常个例。
上传自定义附件
业务可以通过Bugly SDK开放的自定义附件上传接口,以附件的形式,补充更多业务现场。
- Android
- iOS
- Anroid SDK 4.3.0.3版本开始支持自定义附件。
- 使用该接口需要同时初始化Bugly性能和Bugly质量模块,详细参考「SDK接入指引」。
- 自定义文件压缩之后的大小限制为10MB。如果超过该大小,会直接删除,不会上传。
- 该接口可以调用多次,之后的调用会覆盖前面设置的值。
CrashReport.setAdditionalAttachmentPaths(String[] files);
- 自定义文件都在二次启动的时候才会上传。
- SDK默认禁止该功能,开启需要在Portal端新添加如下配置。
- 第二次启动之后可以通过“sub_type: custom_log”关键字日志来确认是否有自定义文件上传。
12-07 20:42:26.673 15758 15862 I RMonitor_report_File: url: https://rmonitor.qq.com/v1/2ff6123857/custom/upload-file?sign=22efd184a95c12d7faaecb8e8edc3266×tamp=1670416946671&nonce=ee48217de804345e1634d0adf58e8825, sub_type: custom_log
- iOS SDK 2.7.51 版本开始支持自定义附件。
- 参考以下代码设置自定义附件的路径,在异常发生后,会在相应目录下,打包附件上传。
/**
* 设置自定义文件的决定路径的集合。
* 文件压缩后的大小不大于10M,二次启动时上报。
*/
+ (void)setAdditionalAttachmentPaths:(NSArray<NSString *>*)pathArray;
使用示例:
[Bugly setAdditionalAttachmentPaths:[NSArray arrayWithObject:filePath]];
- 自定义文件都在二次启动的时候才会上传。
- SDK默认禁止该功能,开启需要在Portal端新添加如下配置。
如果在当前配置中没有看到自定义文件这一项,点击最后一个配置项的最右边的加号icon,添加自定义文件的配置项。
Android
附件概述
分类/Tab | 来源 |
---|---|
出错堆栈 | 来自crash详情接口,导出在附件「crash.log」 |
现场数据/基础信息 | 来自crash详情接口,导出在附件「detail_data.json」 |
现场数据/自定义字段 | 来自附件valueMapOthers.txt |
现场数据/页面跟踪 | 来自附件martianlog.txt |
日志 | 来自附件log.txt |
FD信息 | 来自附件crashInfos.txt |
进程信息 | 来自附件state_file.zip |
通过回调接口「getCrashExtraData」补充的信息 | 导出在附件「userExtraByteData」中 |
通过回调接口「getCrashExtraMessage」补充的信息 | 导出在附件「user_datas.log」中 |
通过CrashReport.putUserData和setUserSceneTag设置的内容 | 导出在附件「valueMapOthers.txt」中 |
ANR_INFO | 来自附件anrMessage.txt |
ANR_Trace | 来自附件trace.zip |
crash.log
存放出错堆栈信息,包含当前异常线程的堆栈,以及其他线程的堆栈,跟出错堆栈Tab展示的内容一致。
- 对于native异常,捕获异常堆栈是同时捕获native堆栈和java堆栈,而且是在native层进行捕获,获取的是native层的进程号。
- 其他线程的堆栈作为附加信息,是在java层处理的,获取的是JVM堆栈,进程号也是JVM中描述的进程号。
- 当前其他线程堆栈其实是包含异常发生时,当前应用所有的JVM线程堆栈,也可能包含当前崩溃的线程,但是没有包含native层创建的线程。
tomb.zip
对应系统的「tombstone」文件,在应用程序或系统进程崩溃时生成。这个文件包含了崩溃时的一些关键信息,如堆栈跟踪、内存映射、寄存器状态等。这个文件是Bugly参考系统的「tombstone」文件格式而生成的。
tombstone包含以下几部分信息:
异常摘要
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Crash type: 'native'
Start time: '2023-12-22T15:55:39.381+0800'
Crash time: '2023-12-22T15:58:30.119+0800'
App version: '4.4.0-beta.3'
Rooted: 'No'
API level: '30'
Build fingerprint: 'vivo/PD1824/PD1824:11/RP1A.200720.012/compiler03061748:user/release-keys'
ABI: 'arm64'
pid: 26730, tid: 26730, name: .example.sdkapp >>> com.example.sdkapp <<<
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'JNI DETECTED ERROR IN APPLICATION: jarray was NULL in call to GetObjectArrayElement from void com.tencent.bugly.crashreport.crash.jni.NativeCrashHandler.testCrash()'
寄存器信息
x0 0000000000000000 x1 000000000000686a x2 0000000000000006 x3 0000007fdab30cc0
x4 00000077f497b000 x5 00000077f497b000 x6 00000077f497b000 x7 000000000042906e
x8 00000000000000f0 x9 b8ae21afa5964f35 x10 0000000000000000 x11 ffffffc0fffffbdf
x12 0000000000000001 x13 00000000658541a6 x14 0005e9acbf980fa7 x15 000077c18d549120
x16 00000077f138b948 x17 00000077f1368630 x18 00000077f3d3a000 x19 000000000000686a
x20 000000000000686a x21 00000000ffffffff x22 000000000000000b x23 000000000000000b
x24 000000776caa41c5 x25 0000000000000001 x26 000000776cabb177 x27 000000776d072000
x28 b4000077f3452340 x29 0000007fdab30d40
sp 0000007fdab30ca0 lr 00000077f1317d24 pc 00000077f1317d50
异常堆栈
backtrace:
#00 pc 000000000008cd50 /apex/com.android.runtime/lib64/bionic/libc.so (abort+164)
#01 pc 00000000005320a0 /apex/com.android.art/lib64/libart.so (_ZN3art7Runtime5AbortEPKc+2340)
#02 pc 000000000001394c /system/lib64/libbase.so (_ZZN7android4base10SetAborterEONSt3__18functionIFvPKcEEEEN3$_38__invokeES4_+76)
#03 pc 00000000000130cc /system/lib64/libbase.so (_ZN7android4base10LogMessageD1Ev+312)
#04 pc 0000000000369b00 /apex/com.android.art/lib64/libart.so (_ZN3art9JavaVMExt8JniAbortEPKcS2_+2596)
#05 pc 0000000000369b78 /apex/com.android.art/lib64/libart.so (_ZN3art9JavaVMExt9JniAbortVEPKcS2_St9__va_list+108)
#06 pc 000000000035b7c4 /apex/com.android.art/lib64/libart.so (_ZN3art12_GLOBAL__N_111ScopedCheck6AbortFEPKcz+144)
...
#81 pc 0000000000088188 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108)
build id
BuildId是一个在编译过程中生成的唯一标识符,用于标识特定的二进制文件。BuildId的主要用途是在调试过程中,帮助开发者确定正在运行的二进制文件的确切版本。在Linux系统中,BuildId通常是通过编译器或链接器在编译过程中生成的,它通常是源代码、编译选项等信息的哈希值。如果两个 ELF 文件具有相同的 build ID,则它们是相同版本的库。
build id:
/apex/com.android.runtime/lib64/bionic/libc.so (BuildId: 4995223f2954ed2746d96c2f1c7939a1. FileSize: 1314184. LastModified: 2009-01-01T08:00:00.000+0800. MD5: 0eabd0f3735afdc6317062180a4369ec)
...
/system/bin/app_process64 (BuildId: c8e30518cdd6709068b3a08e6bfe4a76. FileSize: 33832. LastModified: 2009-01-01T08:00:00.000+0800. MD5: 68ed3a8e223ff95392828c5b5dd451f3)
在mac中,可以直接通过readelf工具读取一个so的BuildID
> readelf -n libnative.so
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: dae1f4c9f93715c9de15c86161a1af37b5cce24a
栈内存
stack:
0000007fdab30c20 00000077f3814000 [anon:stack_and_tls:main]
0000007fdab30c28 0000000000000002
0000007fdab30c30 0000007fdab30d58 [stack]
0000007fdab30c38 0000000000000000
0000007fdab30c40 000000776cac3c9e /apex/com.android.art/lib64/libart.so
0000007fdab30c48 00000077f12d0c84 /apex/com.android.runtime/lib64/bionic/libc.so (malloc+44)
0000007fdab30c50 00000076f4d262c0 [anon:libc_malloc]
0000007fdab30c58 b8ae21afa5964f35
0000007fdab30c60 0000007fdab30d40 [stack]
0000007fdab30c68 00000077f1317ce8 /apex/com.android.runtime/lib64/bionic/libc.so (abort+60)
0000007fdab30c70 000000000000000b
0000007fdab30c78 000000776cac3c9e /apex/com.android.art/lib64/libart.so
0000007fdab30c80 000000000000000b
0000007fdab30c88 00000076fd2b9a00 [anon:libc_malloc]
0000007fdab30c90 00000077f4a797f0 [anon:.bss]
0000007fdab30c98 00000076f4c6e080 [anon:libc_malloc]
#00 0000007fdab30ca0 0000000000000001
...
........ ........
#81 0000007fdab35f80 0000007fdab35fd0 [stack]
0000007fdab35f88 0000005e8de33048 /system/bin/app_process64 (main)
0000007fdab35f90 0000000000000000
0000007fdab35f98 0000000000000000
0000007fdab35fa0 0000000000000000
0000007fdab35fa8 0000000000000000
0000007fdab35fb0 0000000000000000
0000007fdab35fb8 0000005e8de37000 /system/bin/app_process64
0000007fdab35fc0 0000005e8de37010 /system/bin/app_process64
0000007fdab35fc8 0000005e8de37028 /system/bin/app_process64
0000007fdab35fd0 0000000000000000
0000007fdab35fd8 00000077f49caa68 /apex/com.android.runtime/bin/linker64 (__dl__start+8)
0000007fdab35fe0 0000000000000006
0000007fdab35fe8 0000007fdab36290 [stack]
0000007fdab35ff0 0000007fdab362aa [stack]
0000007fdab35ff8 0000007fdab362b3 [stack]
以及通用寄存器附近的内存和内存信息。有关tomb.zip文件的介绍,后续有专门的文章。
detail_data.json
- 基础数据以及页面跟踪是Bugly在异常时自动捕获的现场信息,其中基础数据导出在附件「detail_data.json」中。
- 自定义字段中展示的「APP渠道」,来自「detail_data.json」的"appInfo"。
valueMapOthers.txt
- 自定义字段是指业务通过
CrashReport.putUserData
接口设置的Key/Value, 相关内容导出在附件「valueMapOthers.txt」中。 - 通过
CrashReport.setUserSceneTag
接口设置的Tag,相关内容导出在附件「valueMapOthers.txt」中。 - 自定义字段中展示的「APP渠道」,来自「detail_data.json」的"appInfo"。
- 现场数据的自定义字段部分展示的内容跟附件「valueMapOthers.txt」是一致的。
martianlog.txt
- 异常发生前一段时间的页面追踪数据,由Bugly自动记录。
- 这部分数据同时展示在「现场数据/页面追踪」部分。
log.txt
异常现场的日志Tab中展示的系统日志,对应附件的「log.txt」。
crashInfos.txt
- 异常现场的FD Tab中展示的FD信息,来自附件「crashInfos.txt」。
- 除此之外,附件「crashInfos.txt」还包含 System SO infos
信息来自「/proc/$pid/maps」文件。
System SO infos:
707dd000-70a50000 r-xp 00080000 fc:00 171 /apex/com.android.art/javalib/arm64/boot.oat
70a65000-70ab7000 r-xp 00010000 fc:00 165 /apex/com.android.art/javalib/arm64/boot-core-libart.oat
...
以第一行举例,这些信息描述了SO文件在内存中的位置、访问权限以及在磁盘上的偏移量等相关信息。
- "707dd000-70a50000":这是文件在内存中的地址范围。它表示文件被映射到内存的起始地址是0x707dd000,结束地址是0x70a50000。
- "r-xp":这是文件在内存中的访问权限。其中,"r"表示可读,"x"表示可执行,"p"表示私有。
- "00080000":这是文件在磁盘上的偏移量,表示文件在磁盘中的起始位置距离文件开头的偏移量是0x00080000。
- "fc:00":这是文件的设备号和inode号,用于唯一标识文件。
- "171":这是文件的文件描述符,用于在操作系统中标识文件。
tomb.zip 中的stack也是根据这些信息,标识出一些地址对应的SO文件。
state_file.zip
- 异常详情中,「进程信息」来自附件「state_file.zip」中。
- Maps信息来自「/proc/$pid/maps」文件。
- Meminfo信息表示了用户进程的内存使用情况,可以查看应用当前内存主要被如何分配。
- 进程状态和线程状态分别表示当前运行进程及其中各线程的状态指标。
user_datas.log
- 通过回调接口「getCrashExtraMessage」补充的信息导出在附件「user_datas.log」中。
extraMessage.txt
- 通过回调接口「getCrashExtraData」补充的信息导出在附件「extraMessage.txt」中。
alltimes.txt
- 一个应用连续发生了多次相同异常,这些相同的异常会合并为一条异常进行上报。
- 「alltimes.txt」保存的就是被合并的异常的发生时间明细。
- 每一次发生时间会保存为一行,时间取的是Unix时间,单位是毫秒。
anrMessage.txt
- 「anrMessage.txt」的信息展示在「ANR_INFO」中。
- ANR_INFO信息是应用程序在ANR发生时生成的一项系统报告,记录了ANR发生时所在的Activity组件,发生ANR的进程ID,以及发生ANR的原因。
- 其中,
Load
表示ANR发生时系统在1分钟、5分钟和15分钟的平均负载情况,平均负载的单位是进程数,代表在ANR发生时系统中正在运行或等待CPU资源的进程数的平均值。CPU Usage
代表在ANR发生的时间范围内CPU的详细占用情况,根据这些信息可以辅助进行ANR问题的分析。
trace.zip
- 「trace.zip」的信息展示在「ANR Trace」中。
- ANR Trace是一个包含应用程序在ANR期间发生的事件和线程堆栈跟踪的日志文件。
- 第一部份是ANR时间和GC信息,可以了解当前ANR问题发生了多长时间,系统进行了哪些GC操作。
- 第二部份是线程堆栈信息,列出了所有在ANR期间运行线程的堆栈跟踪信息。除每个线程除堆栈信息外,还包含线程ID(tid)、线程优先级(prio)、线程状态(state)、线程调度统计信息(schedstat)、线程使用的CPU时间(utm和stm)等线程的状态信息。结合上述信息,尤其是线程的堆栈跟踪信息,可以快速帮助定位分析造成ANR问题的原因。
iOS
附件概述
- ios平台暂不支持日志;
分类/Tab | 来源 |
---|---|
出错堆栈 | 来自crash详情接口,导出在附件「crash.log」 |
现场数据/基础信息 | 来自crash详情接口,导出在附件「detail_data.json」 |
现场数据/自定义字段 | 来自附件valueMapOthers.txt |
现场数据/页面跟踪 | 来自附件martianlog.txt |
通过接口「setUserValue」补充的信息 | 导出在附件「user_datas.log」中 |
通过回调接口「attachmentForException」补充的信息 | 导出在附件「crash_attach.log」中 |
内存信息 | 附件「meminfo.txt」 |
crash.log
- 存放出错堆栈信息,包含当前异常线程的堆栈,以及其他线程的堆栈,跟出错堆栈Tab展示的内容一致;
- 不同线程的堆栈通过空行分割,首行是线程号以及线程名;
- 包含当前异常线程的寄存器信息;
- 包含所有模块的信息;
detail_data.json
- 基础数据以及页面跟踪是Bugly在异常时自动捕获的现场信息,其中基础数据导出在附件「detail_data.json」中。
- 自定义字段中展示的「APP渠道」,来自「detail_data.json」的"appInfo"。
valueMapOthers.txt
- 包含业务通过接口setUserValue设置的内容;
- 现场数据的自定义字段部分展示的内容跟附件「valueMapOthers.txt」是一致的;
martianlog.txt
- 异常发生前一段时间的页面追踪数据,由Bugly自动记录。
- 这部分数据同时展示在「现场数据/页面追踪」部分。
user_datas.log
- 包含业务通过接口setUserValue设置的内容;
- 现场数据的自定义字段部分展示的内容跟附件「user_datas.log」是一致的;
crash_attach.log
- 业务通过回调接口attachmentForException设置的内容;
meminfo.txt
- 异常时的内存概述信息;