一、Cpp Crash异常检测能力
进程崩溃基于posix信号机制,目前主要支持对以下崩溃异常信号的处理:
信号值(signo) | 信号 | 解释 | 触发原因 |
---|---|---|---|
4 | SIGILL | 非法指令。 | 进程执行了非法、格式错误、未知或特权指令。 |
5 | SIGTRAP | 断点或陷阱异常。 | 异常或trap指令发生。 |
6 | SIGABRT | 进程终止。 | 进程异常终止,通常为进程自身调用标准函数库的abort()函数。 |
7 | SIGBUS | 非法内存访问。 | 进程访问了对齐或者不存在的物理地址。 |
8 | SIGFPE | 浮点异常。 | 进程执行了错误的算术运算,如除数为0、浮点溢出、整数溢出等。 |
11 | SIGSEGV | 无效内存访问。 | 进程访问了无效内存引用。 |
16 | SIGSTKFLT | 栈错误。 | 处理器执行了错误的栈操作,如栈空时弹出、栈满时压入。 |
31 | SIGSYS | 错误的系统调用。 | 系统调用时使用了错误或非法参数。 |
以上部分故障信号,根据具体的场景还有二级分类(code):
SIGILL是一个在Unix和类Unix操作系统中的信号,它表示非法指令异常。SIGILL信号通常由以下几种类型的问题场景引起:
二级分类 | 信号字符串 | 解释 | 触发原因 |
---|---|---|---|
1 | ILL_ILLOPC | 非法操作码异常 | 这种异常通常发生在执行不被CPU支持的指令时,或者在尝试执行特权指令时。 |
2 | ILL_ILLOPN | 非法操作数异常 | 这种异常通常发生在指令使用了不正确的操作数,或者是操作数的类型不正确时。 |
3 | ILL_ILLADR | 非法地址异常 | 这种异常通常发生在程序尝试访问无效的内存地址时,或者是在尝试执行未对齐的内存访问时。 |
4 | ILL_ILLTRP | 非法陷阱异常 | 这种异常通常发生在程序尝试执行一个非法的陷阱指令时,或者是在尝试执行一个未定义的操作时。 |
5 | ILL_PRVOPC | 特权操作码异常 | 这种异常通常发生在普通用户尝试执行特权指令时。 |
6 | ILL_PRVREG | 特权寄存器异常 | 这种异常通常发生在普通用户尝试访问特权寄存器时。 |
7 | ILL_COPROC | 协处理器异常 | 这种异常通常发生在程序尝试使用未定义的协处理器指令时。 |
8 | ILL_BADSTK | 无效的堆栈异常 | 这种异常通常发生在程序尝试在无效的堆栈地址上执行操作时,或者是在堆栈溢出时。 |
SIGTRAP信号通常用于调试和跟踪程序的执行。下面是上面列出的四种SIGTRAP信号类别的问题场景介绍:
二级分类 | 信号字符串 | 解释 | 触发原因 |
---|---|---|---|
1 | TRAP_BRKPT | 软件断点 | 这个信号是由软件断点引起的,当程序执行到设置的断点时会触发该信号。软件断点通常用于调试程序,可以在程序的关键位置设置断点,以便在调试时暂停程序的执行并检查变量值等信息。 |
2 | TRAP_TRACE | 单步调试 | 这个信号是由单步执行引起的,当程序执行单个指令时会触发该信号。单步执行通常用于调试程序,可以逐步执行程序并检查每个指令的执行结果。 |
3 | TRAP_BRANCH | 分支跟踪 | 这个信号是由分支指令引起的,当程序执行分支指令时会触发该信号。分支指令通常用于控制程序的执行流程,例如if语句和循环语句等。 |
4 | TRAP_HWBKPT | 硬件断点 | 这个信号是由硬件断点引起的,当程序执行到设置的硬件断点时会触发该信号。硬件断点通常用于调试程序,可以在程序的关键位置设置断点,以便在调试时暂停程序的执行并检查变量值等信息。与软件断点不同的是,硬件断点是由CPU硬件实现的,因此可以在程序执行过程中实时检测断点是否被触发。 |
SIGBUS是一种由操作系统向进程发送的信号,通常表示内存访问错误。其中,不同的信号类别表示不同的错误场景:
二级分类 | 信号字符串 | 解释 | 触发原因 |
---|---|---|---|
1 | BUS_ADRALN | 内存地址对齐错误 | 这种错误通常发生在尝试访问未对齐的内存地址时,例如尝试访问一个4字节整数的非偶数地址。 |
2 | BUS_ADRERR | 非法内存地址错误 | 这种错误通常发生在尝试访问不属于进程地址空间的内存地址时,例如尝试访问一个空指针。 |
3 | BUS_OBJERR | 对象访问错误 | 这种错误通常发生在尝试访问一个已经被删除或未初始化的对象时。 |
4 | BUS_MCEERR_AR | 硬件内存校验错误 | 发生在访问内存时检测到校验和错误。 |
5 | BUS_MCEERR_AO | 硬件内存校验错误 | 发生在访问内存时检测到地址和校验和错误。 |
SIGFPE是一个信号,它表示浮点异常或算术异常。下面是这些SIGFPE信号类别的问题场景:
二级分类 | 信号字符串 | 解释 | 触发原因 |
---|---|---|---|
1 | FPE_INTDIV | 整数除法错误 | 这个信号表示整数除法中的除数为零的情况。当一个程序尝试进行整数除法,但除数为零时,会发出这个信号。 |
2 | FPE_INTOVF | 整数溢出错误 | 这个信号表示整数除法中的除数为负数的情况。当一个程序尝试进行整数除法,但除数为负数时,会发出这个信号。 |
3 | FPE_FLTDIV | 浮点除法错误 | 这个信号表示浮点数除法中的除数为零的情况。当一个程序尝试进行浮点数除法,但除数为零时,会发出这个信号。 |
4 | FPE_FLTOVF | 浮点溢出错误 | 这个信号表示浮点数除法中的除数为负数的情况。当一个程序尝试进行浮点数除法,但除数为负数时,会发出这个信号。 |
5 | FPE_FLTUND | 浮点下溢错误 | 这个信号表示浮点数除法中的除数为零的情况。当一个程序尝试进行浮点数除法,但除数为零时,会发出这个信号。 |
6 | FPE_FLTRES | 浮点结果未定义错误 | 这个信号表示浮点数除法中的除数为正数的情况。当一个程序尝试进行浮点数除法,但除数为正数时,会发出这个信号。 |
7 | FPE_FLTINV | 无效浮点操作错误 | 这个信号表示浮点数除法中的除数为负数的情况。当一个程序尝试进行浮点数除法,但除数为负数时,会发出这个信号。 |
8 | FPE_FLTSUB | 浮点陷阱错误 | 这个信号表示浮点数除法中的除数为零的情况。当一个程序尝试进行浮点数除法,但除数为零时,会发出这个信号。 |
SIGSEGV是一种信号,它表示进程试图访问一个不属于它的内存地址,或者试图访问一个已被操作系统标记为不可访问的内存地址。SIGSEGV信号通常是由以下两种情况引起的:
二级分类 | 信号字符串 | 解释 | 触发原因 |
---|---|---|---|
1 | SEGV_MAPERR | 不存在的内存地址 | 进程试图访问一个不存在的内存地址,或者试图访问一个没有映射到进程地址空间的内存地址。这种情况通常是由于程序中的指针错误或内存泄漏引起的。 |
2 | SEGV_ACCERR | 不可访问的内存地址 | 进程试图访问一个已被操作系统标记为不可访问的内存地址,例如只读内存或没有执行权限的内存。这种情况通常是由于程序中的缓冲区溢出或者试图修改只读内存等错误引起的。 |
二级分类(code)除了以上根据信号值(signo)维度分类,还可以根据信号产生的原因维度分类。其中根据信号值(signo)维度分类是每个信号值(signo)特有的,根据信号产生的原因维度分类是所有信号值(signo)共有的,当前已有信号产生原因分类的code值如下:
二级分类 | 信号字符串 | 解释 | 触发原因 |
---|---|---|---|
0 | SI_USER | 用户空间信号 | 该信号是由用户空间的进程发送给另一个进程的,通常是通过 kill() 系统调用发送的。例如,当用户在终端中按下Ctrl+C时,会发送一个SIGINT信号给前台进程组中的所有进程。 |
0x80 | SI_KERNEL | 内核信号 | 该信号是由内核发送给进程的,通常是由内核检测到某些错误或异常情况时发出的。例如,当进程访问无效的内存地址或者执行非法指令时,内核会发送一个SIGSEGV信号给进程。 |
-1 | SI_QUEUE | sigqueue()函数信号 | 该信号是由sigqueue()系统调用发送的,可以携带一个附加的整数值和一个指针。通常用于进程间高级通信,例如传递数据或者通知进程某个事件已经发生。 |
-2 | SI_TIMER | 定时器信号 | 该信号是由定时器发送的,通常用于定时任务或者周期性任务的执行。例如,当一个定时器到期时,内核会向进程发送一个SIGALRM信号。 |
-3 | SI_MESGQ | 消息队列信号 | 该信号是由消息队列发送的,通常用于进程间通信。例如,当一个进程向一个消息队列发送消息时,内核会向接收进程发送一个SIGIO信号。 |
-4 | SI_ASYNCIO | 异步I/O信号 | 该信号是由异步I/O操作发送的,通常用于非阻塞I/O操作。例如,当一个文件描述符上的I/O操作完成时,内核会向进程发送一个SIGIO信号。 |
-5 | SI_SIGIO | 同步I/O信号 | 该信号是由异步I/O操作发送的,通常用于非阻塞I/O操作。例如,当一个文件描述符上的I/O操作完成时,内核会向进程发送一个SIGIO信号。 |
-6 | SI_TKILL | tkill()函数信号 | 该信号是由tkill()系统调用发送的,与kill()系统调用类似,但是可以指定发送信号的线程ID。通常用于多线程程序中,向指定线程发送信号。 |
二、问题定位步骤与思路
1、崩溃日志获取
进程崩溃日志是一种故障日志,与应用无响应日志、JS应用崩溃等都由FaultLogger模块进行管理,可通过以下方式获取:
(1)通过DevEco Studio获取日志
DevEco Studio会收集设备/data/log/faultlog/faultlogger/路径下的进程崩溃故障日志到FaultLog下,根据进程名和故障和时间分类显示。
(2)通过hiAppEvent接口订阅
hiAppEvent 提供了故障订阅接口,可以订阅各类故障打点。
2、日志格式
(1)空指针故障场景
该场景会在日志中打印出提示信息,表明故障很有可能时因为空指针解引用导致。
以下是一份DevEco Studio归档在FaultLog的进程崩溃日志的核心内容,与设备/data/log/faultlog/faultlogger下归档的日志内容相同。
Generated by HiviewDFX@HarmonyOS
================================================================
Device info:HarmonyOS 3.2 <- 设备信息
Build info:HarmonyOS 5.0.0.23 <- 版本信息
Fingerprint:cdf52fd0cc328fc432459928f3ed8edfe8a72a92ee7316445143bed179138073 <- 标识故障特征
Module name:crasher_cpp <- 模块名
Timestamp:2024-05-06 20:10:51.000 <- 故障发生时间戳
Pid:9623 <- 进程号
Uid:0 <- 用户ID
Process name:./crasher_cpp <- 进程名称
Process life time:1s <- 进程存活时间
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0x00000004 probably caused by NULL pointer dereference <- 故障原因和空指针提示
Fault thread info:
Tid:9623, Name:crasher_cpp <- 故障线程号,线程名
#00 pc 00008d22 /system/bin/crasher_cpp(TestNullPointerDereferenceCrash0()+22)(adfc673300571d2da1e47d1d12f48b44) <- 调用栈
#01 pc 000064d1 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+160)(adfc673300571d2da1e47d1d12f48b44)
#02 pc 00006569 /system/bin/crasher_cpp(main+92)(adfc673300571d2da1e47d1d12f48b44)
#03 pc 00072b98 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(d820b1827e57855d4f9ed03ba5dfea83)
#04 pc 00004e28 /system/bin/crasher_cpp(_start_c+84)(adfc673300571d2da1e47d1d12f48b44)
#05 pc 00004dcc /system/bin/crasher_cpp(adfc673300571d2da1e47d1d12f48b44)
Registers: <- 故障现场寄存器
r0:ffffafd2 r1:00000004 r2:00000001 r3:00000000
r4:ffd27e39 r5:0096e000 r6:00000a40 r7:0096fdfc
r8:f7ba58d5 r9:f7baea86 r10:f7cadd38
fp:ffd27308 ip:f7cb2078 sp:ffd272a0 lr:f7c7ab98 pc:0096ad22
Memory near registers: <- 故障现场寄存器附近内存
r4([stack]):
ffd27e30 72656873
ffd27e34 7070635f
...
ffd27eac 3d73746f
r5(/system/bin/crasher_cpp):
0096dff8 00000000
0096dffc 0096717d
...
0096e074 00000000
r7(/system/lib/ld-musl-arm.so.1):
f7cabb58 00000000
f7cabb5c 0034ba00
...
f7cabbd4 00000000
r8(/system/lib/ld-musl-arm.so.1):
f7ba58cc 63637573
f7ba58d0 2e737365
...
f7ba5948 70206269
r9(/system/lib/ld-musl-arm.so.1):
f7baea7c 20746f6e
f7baea80 6e756f66
...
f7baeaf8 25206e69
r10([anon:ld-musl-arm.so.1.bss]):
f7cadd30 00000000
f7cadd34 00000000
...
f7caddac 00000000
r12([anon:ld-musl-arm.so.1.bss]):
f7cb2070 56726562
f7cb2074 65756c61
...
f7cb20ec 00000000
sp([stack]):
ffd27328 00000000
ffd2732c 00966dd0
...
ffd273a4 00000004
pc(/system/bin/crasher_cpp):
00966dc8 e1a0d00c
00966dcc eb000000
...
00966e44 e5907008
pc(/system/bin/crasher_cpp):
00966dc8 e1a0d00c
00966dcc eb000000
...
00966e44 e5907008
FaultStack: <- 崩溃线程的栈地址空间
ffd27260 00000000
ffd27264 f7cac628
...
ffd2729c 0096ad1f
sp0:ffd272a0 0096fdfc <- #00栈顶
ffd272a4 009684d3
sp1:ffd272a8 00000001
ffd272ac 73657408
ffd272b0 f7590074
...
ffd272dc 0096856d
sp2:ffd272e0 ffd27334
ffd272e4 ffd27334
ffd272e8 00000002
....
ffd272f4 f7bfbb9c
sp3:ffd272f8 00000000
ffd272fc ffd27334
Maps: <- 故障时进程maps
962000-966000 r--p 00000000 /system/bin/crasher_cpp
966000-96c000 r-xp 00003000 /system/bin/crasher_cpp
96c000-96f000 r--p 00008000 /system/bin/crasher_cpp
96f000-970000 rw-p 0000a000 /system/bin/crasher_cpp
149f000-14a0000 ---p 00000000 [heap]
14a0000-14a2000 rw-p 00000000 [heap]
...
f7b89000-f7be1000 r--p 00000000 /system/lib/ld-musl-arm.so.1
f7be1000-f7ca9000 r-xp 00057000 /system/lib/ld-musl-arm.so.1
f7ca9000-f7cab000 r--p 0011e000 /system/lib/ld-musl-arm.so.1
f7cab000-f7cad000 rw-p 0011f000 /system/lib/ld-musl-arm.so.1
f7cad000-f7cbc000 rw-p 00000000 [anon:ld-musl-arm.so.1.bss]
ffd07000-ffd28000 rw-p 00000000 [stack]
ffff0000-ffff1000 r-xp 00000000 [vectors]
OpenFiles: <- 故障时进程打开文件Fd信息
0->/dev/pts/1 native object of unknown type 0
1->/dev/pts/1 native object of unknown type 0
2->/dev/pts/1 native object of unknown type 0
3->socket:[67214] native object of unknown type 0
...
11->pipe:[67219] native object of unknown type 0
12->socket:[29074] native object of unknown type 0
25->/dev/ptmx native object of unknown type 0
26->/dev/ptmx native object of unknown type 0
HiLog: <- 故障时的Hilog日志
05-06 20:10:51.301 9623 9623 E C03f00/MUSL-SIGCHAIN: signal_chain_handler call 2 rd sigchain action for signal: 11
05-06 20:10:51.306 9623 9623 I C02d11/DfxSignalHandler: DFX_SigchainHandler :: sig(11), pid(9623), tid(9623).
05-06 20:10:51.307 9623 9623 I C02d11/DfxSignalHandler: DFX_SigchainHandler :: sig(11), pid(9623), processName(./crasher_cpp), threadName(crasher_cpp).
05-06 20:10:51.389 9623 9623 I C02d11/DfxSignalHandler: processdump have get all resgs
(2)栈溢出故障场景
该场景会在日志中打印出提示信息,表明故障很有可能时因为栈溢出导致。核心日志如下:
Generated by HiviewDFX@HarmonyOS
================================================================
Device info:HarmonyOS 3.2 <- 设备信息
Build info:HarmonyOS 5.0.0.23 <- 版本信息
Fingerprint:8bc3343f50024204e258b8dce86f41f8fcc50c4d25d56b24e71fe26c0a23e321 <- 标识故障特征
Module name:crasher_cpp <- 模块名
Timestamp:2024-05-06 20:18:24.000 <- 故障发生时间戳
Pid:9838 <- 进程号
Uid:0 <- 用户ID
Process name:./crasher_cpp <- 进程名称
Process life time:2s <- 进程存活时间
Reason:Signal:SIGSEGV(SEGV_ACCERR)@0xf76b7ffc current thread stack low address = 0xf76b8000, probably caused by stack-buffer-overflow <- 故障原因和栈溢出提示
...
(3)栈覆盖故障场景
在栈覆盖场景下,由于栈上内存被踩,无法成功回溯栈帧,该场景会在日志中打印出提示信息,说明回栈失败并尝试从线程栈里解析获取不可靠的调用栈,尽可能提供开发者信息以分析问题。核心日志如下:
Generated by HiviewDFX@HarmonyOS
================================================================
Device info:HarmonyOS 3.2 <- 设备信息
Build info:HarmonyOS 5.0.0.23 <- 版本信息
Fingerprint:79b6d47b87495edf27135a83dda8b1b4f9b13d37bda2560d43f2cf65358cd528 <- 标识故障特征
Module name:crasher_cpp <- 模块名
Timestamp:2024-05-06 20:27:23.2035266415 <- 故障发生时间戳
Pid:10026 <- 进程号
Uid:0 <- 用户ID
Process name:./crasher_cpp <- 进程名称
Process life time:1s <- 进程存活时间
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0000000000 probably caused by NULL pointer dereference <- 故障原因
LastFatalMessage: Failed to unwind stack, try to get unreliable call stack from #02 by reparsing thread stack <- 尝试从线程栈里获取不可靠的堆栈
Fault thread info:
Tid:10026, Name:crasher_cpp <- 故障线程号,线程名
#00 pc 00000000 Not mapped
#01 pc 00008d22 /system/bin/crasher_cpp(TestNullPointerDereferenceCrash0()+22)(adfc673300571d2da1e47d1d12f48b44) <- 调用栈
#02 pc 000064d1 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+160)(adfc673300571d2da1e47d1d12f48b44)
#03 pc 00006569 /system/bin/crasher_cpp(main+92)(adfc673300571d2da1e47d1d12f48b44)
#04 pc 00072b98 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(d820b1827e57855d4f9ed03ba5dfea83)
...
(4)异步线程场景故障
(目前支持ARM64架构,且在调试应用(HAP_DEBUGGABLE)下开启)
当异步线程发生崩溃后,把提交该异步任务的线程的栈也打印出来,帮助定位由于异步任务提交者造成的崩溃问题。崩溃线程的调用栈和其提交线程的调用栈用SubmitterStacktrace分割开。核心日志如下:
Generated by HiviewDFX@HarmonyOS
================================================================
Device info:HarmonyOS 3.2 <- 设备信息
Build info:HarmonyOS 5.0.0.23 <- 版本信息
Fingerprint:8bc3343f50024204e258b8dce86f41f8fcc50c4d25d56b24e71fe26c0a23e321 <- 标识故障特征
Module name:crasher_cpp <- 模块名
Timestamp:2024-05-06 20:28:24.000 <- 故障发生时间戳
Pid:9838 <- 进程号
Uid:0 <- 用户ID
Process name:./crasher_cpp <- 进程名称
Process life time:2s <- 进程存活时间
Reason:Signal:SIGSEGV(SI_TKILL)@0x000000000004750 from:18256:0 <- 故障原因
Fault thread info:
Tid:18257, Name:crasher_cpp <- 故障线程号,线程名
#00 pc 000054e6 /system/bin/ld-musl-aarch64.so.l(raise+228)(adfc673300571d2da1e47d1d12f48b44) <- 调用栈
#01 pc 000054f9 /system/bin/crasher_cpp(CrashInSubThread(void*)+56)(adfc673300571d2da1e47d1d12f48b50)
#02 pc 000054f9 /system/bin/ld-musl-aarch64.so.l(start+236)(adfc673300571d2da1e47d1d12f48b44)
========SubmitterStacktrace======== <- 任务异常时打印任务提交者调用栈
#00 pc 000094dc /system/bin/crasher_cpp(DfxCrasher::AsyncStacktrace()+36)(adfc673300571d2da1e47d1d12f48b50)
#01 pc 00009a58 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+232)(adfc673300571d2da1e47d1d12f48b50)
#02 pc 00009b40 /system/bin/crasher_cpp(main+140)(adfc673300571d2da1e47d1d12f48b50)
#03 pc 0000a4e1c /system/bin/ld-musl-aarch64.so.l(libc_start_main_stage2+68)(adfc673300571d2da1e47d1d12f48b44)
...
3、基于崩溃栈定位行号
(1)DevEco Studio 开发者环境下,支持调用栈直接跳转到对应行号
在应用开发场景,对于应用自身的动态库,生成的cppcrash堆栈可直接跳转到代 码行处,支持Native栈帧和JS栈帧,无需开发者自行进行解行号操作。对于部分未能解析跳转到对应行号的栈帧,可参考方式二解析。
(2)通过SDK llvm-addr2line 工具定位行号
a、获取符号表
获取崩溃栈中so文件对应的带符号版本,保证与应用/系统内运行时的so文件版本一致。
对于应用自身的动态库,经DevEco编译构建,生成在工程的 /build/default/intermediates/libs 目录下,默认是带符号的版本。可通过Linux file 命令查询二进制文件的 BuildID 以核对是否匹配。其中,BuildID 是用于标识二进制文件的唯一标识符,通常由编译器在编译时生成,not stripped 表示该动态库是包含符号表的。
$ file libbabel.so
libbabel.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fdb1b5432b9ea4e2a3d29780c3abf30e2a22da9d, with debug_info, not stripped
b、通过 llvm-addr2line 工具定位行号
llvm-addr2line 工具归档在:[SDK DIR PATH]\HarmonyOS\11\native\llvm\bin 路径下。根据实际的SDK版本路径略有不同,开发者请自行识别或在路径下搜索。
例如有堆栈如下(有省略):
Generated by HiviewDFX@HarmonyOS
================================================================
Device info:HarmonyOS 3.2
Build info:HarmonyOS 5.0.0.22
Fingerprint:50577c0a1a1b5644ac030ba8f08c241cca0092026b59f29e7b142d5d4d5bb934
Module name:com.samples.recovery
Version:1.0.0
VersionCode:1000000
PreInstalled:No
Foreground:No
Timestamp:2017-08-05 17:03:40.000
Pid:2396
Uid:20010044
Process name:com.samples.recovery
Process life time:7s
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0000000000 probably caused by NULL pointer dereference
Tid:2396, Name:amples.recovery
# 00 pc 00003510 /data/storage/el1/bundle/libs/arm/libentry.so(TriggerCrash(napi_env__*, napi_callback_info__*)+24)(446ff75d3f6a518172cc52e8f8055650b02b0e54)
# 01 pc 0002b0c5 /system/lib/platformsdk/libace_napi.z.so(panda::JSValueRef ArkNativeFunctionCallBack<true>(panda::JsiRuntimeCallInfo*)+448)(a84fbb767fd826946623779c608395bf)
# 02 pc 001e7597 /system/lib/platformsdk/libark_jsruntime.so(panda::ecmascript::EcmaInterpreter::RunInternal(panda::ecmascript::JSThread*, unsigned char const*, unsigned long long*)+14710)(106c552f6ce4420b9feac95e8b21b792)
# 03 pc 001e0439 /system/lib/platformsdk/libark_jsruntime.so(panda::ecmascript::EcmaInterpreter::Execute(panda::ecmascript::EcmaRuntimeCallInfo*)+984)(106c552f6ce4420b9feac95e8b21b792)
...
# 39 pc 00072998 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(5b1e036c4f1369ecfdbb7a96aec31155)
# 40 pc 00005b48 /system/bin/appspawn(_start_c+84)(cb0631260fa74df0bc9b0323e30ca03d)
# 41 pc 00005aec /system/bin/appspawn(cb0631260fa74df0bc9b0323e30ca03d)
Registers:
r0:00000000 r1:ffc47af8 r2:00000001 r3:f6555c94
r4:00000000 r5:f4d90f64 r6:bd8434f8 r7:00000000
r8:00000000 r9:ffc48808 r10:ffc47b70
fp:f7d8a5a0 ip:00000000 sp:ffc47aac lr:f4d6b0c7 pc:bd843510
(3)通过 DevEco Studio hstack 工具解析堆栈信息
hstack是DevEco Studio为开发人员提供的用于将release应用混淆后的crash堆栈还原为源码对应堆栈的工具,支持Windows、Mac、Linux三个平台。