准备一段崩溃
-
我们在打开AndroidStudio后,会引导你创建一个C++项目。
-
打开CPP文件,制造一个空指针异常
- 运行程序将得到如下崩溃:
01-09 16:59:55.648 30208 30208 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-09 16:59:55.648 30208 30208 F DEBUG : Build fingerprint: 'HUAWEI/EVR-AN00/HWEVR:9/HUAWEIEVR-AN00/9.1.1.205C00:user/release-keys'
01-09 16:59:55.648 30208 30208 F DEBUG : Revision: '0'
01-09 16:59:55.648 30208 30208 F DEBUG : ABI: 'arm64'
01-09 16:59:55.648 30208 30208 F DEBUG : Happend: 'Thu Jan 9 16:59:55 2020
01-09 16:59:55.648 30208 30208 F DEBUG : '
01-09 16:59:55.648 30208 30208 F DEBUG : SYSVMTYPE: Maple
01-09 16:59:55.648 30208 30208 F DEBUG : APPVMTYPE: Art
01-09 16:59:55.648 30208 30208 F DEBUG : pid: 30173, tid: 30173, name: loud.faster.cpp >>> com.cloud.faster.cpp <<<
01-09 16:59:55.648 30208 30208 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
01-09 16:59:55.648 30208 30208 F DEBUG : x0 0000000000000000 x1 00000000000075dd x2 0000000000000006 x3 0000000000000008
01-09 16:59:55.648 30208 30208 F DEBUG : x4 fefefefeff27feff x5 fefefefeff27feff x6 fefefefeff27feff x7 7f7f7f7f7f7f7f7f
01-09 16:59:55.648 30208 30208 F DEBUG : x8 0000000000000083 x9 41c3e0e68b74670c x10 0000000000000000 x11 fffffffc7ffffbdf
01-09 16:59:55.648 30208 30208 F DEBUG : x12 0000000000000001 x13 ffffffffffffffff x14 0000000000000000 x15 ffffffffffffffff
01-09 16:59:55.648 30208 30208 F DEBUG : x16 000000754fd302c0 x17 000000754fc6ee34 x18 00000074af139153 x19 00000000000075dd
01-09 16:59:55.648 30208 30208 F DEBUG : x20 00000000000075dd x21 00000074ae43b000 x22 00000074c2c1f460 x23 00000074af119c3c
01-09 16:59:55.648 30208 30208 F DEBUG : x24 0000000000000004 x25 0000007551a8f5e0 x26 00000074cb215ca0 x27 0000000000000001
01-09 16:59:55.648 30208 30208 F DEBUG : x28 0000007fe5dbfa60 x29 0000007fe5dbf880
01-09 16:59:55.648 30208 30208 F DEBUG : sp 0000007fe5dbf840 lr 000000754fc63960 pc 000000754fc63988
01-09 16:59:55.754 30208 30208 F DEBUG :
01-09 16:59:55.754 30208 30208 F DEBUG : backtrace:
01-09 16:59:55.754 30208 30208 F DEBUG : #00 pc 0000000000022988 /system/lib64/libc.so (abort+116)
01-09 16:59:55.754 30208 30208 F DEBUG : #01 pc 000000000000d458 /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so (__gnu_cxx::__verbose_terminate_handler()+348)
01-09 16:59:55.754 30208 30208 F DEBUG : #02 pc 0000000000007974 /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so (__cxxabiv1::__terminate(void (*)())+8)
01-09 16:59:55.754 30208 30208 F DEBUG : #03 pc 00000000000079e0 /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so (std::terminate()+12)
01-09 16:59:55.754 30208 30208 F DEBUG : #04 pc 0000000000007b1c /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so (__cxa_throw+136)
01-09 16:59:55.754 30208 30208 F DEBUG : #05 pc 000000000000d604 /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so
01-09 16:59:55.754 30208 30208 F DEBUG : #06 pc 0000000000008334 /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so
01-09 16:59:55.754 30208 30208 F DEBUG : #07 pc 0000000000006e3c /data/app/com.cloud.faster.cpp-RKZrBztu4KB6hTWVqP32sQ==/lib/arm64/libnative-lib.so (Java_com_cloud_faster_cpp_MainActivity_stringFromJNI+60)
初级工具ndk-stack:
ndk-stack是ndk开发工具包下提供的好用工具,能结合崩溃日志给出详细分析
基础用法: ndk-stack -sym 带有符号表的so所在的目录 -dump 崩溃日志
比如
~/Library/Android/sdk/ndk/android-ndk-r16b/ndk-stack -sym app/build/intermediates/cmake/debug/obj/arm64-v8a -dump crash.log
使用addr2line,解析出映射的符号表
以下为python脚本:
#!/usr/bin/env python
# coding=utf-8
import os
# 配置addr2line工具的位置
addr2lineFilePath = '/Users/jian/Library/Android/sdk/ndk/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line'
# 配置符号表so,也就是没有压缩过的so,体积比较大的so
symbolFilePath = 'libflash-downloader-lib.so'
# 崩溃的日志
crashFilePath = 'NdkCrash.log'
command_line_header = addr2lineFilePath + ' -e ' + symbolFilePath + ' '
print('开始解析\n', end='')
with open(crashFilePath, 'r') as file:
keyString = " pc "
for line in file:
# 是否包含关键字:pc
begin = line.find(keyString) + len(keyString)
# 是否包含关键字,关键字之前是否有#
if begin < 0 or line[:begin].find('#') < 0:
print(line, end='')
continue
end = line[begin:].find(' ') + begin
# 补充空格
print(' ' * begin, end='')
print('\u001b[1;36m ' + '↱' + line[begin:end] + '⇨', end='')
# 解析调用栈
command = command_line_header + line[begin:end]
f = os.popen(command)
print('\u001b[31m' + f.read() + ' \u001b[0m ', end='')
f.close()
print(line, end='')