这里以一个实际的crash案例未demo进行分析和讲解。针对native的崩溃信息。一般来讲,较快的方式是直接检索到backtrace,然后通过分析和使用工具addr2line和 ndk-stack等定位到出问题的地方。这里截取了一段 崩溃日志,具体如下:

01-15 14:53:40.240 21741 21741 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-15 14:53:40.240 21741 21741 F DEBUG   : Build fingerprint: 'Android/aosp_crosshatch/crosshatch:12/SP1A.210812.016.C1/eng.wangdsh.20221201.112332:userdebug/test-keys'
01-15 14:53:40.240 21741 21741 F DEBUG   : Revision: 'MP1.0'
01-15 14:53:40.240 21741 21741 F DEBUG   : ABI: 'arm64'
01-15 14:53:40.240 21741 21741 F DEBUG   : Timestamp: 2023-01-15 14:53:39.511121659+0800
01-15 14:53:40.240 21741 21741 F DEBUG   : Process uptime: 0s
01-15 14:53:40.240 21741 21741 F DEBUG   : Cmdline: com.ags.test
01-15 14:53:40.240 21741 21741 F DEBUG   : pid: 21179, tid: 21720, name: SL:21688_21707  >>> com.ags.test <<<
01-15 14:53:40.240 21741 21741 F DEBUG   : uid: 10356
01-15 14:53:40.240 21741 21741 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc0
01-15 14:53:40.240 21741 21741 F DEBUG   : Cause: null pointer dereference
01-15 14:53:40.240 21741 21741 F DEBUG   :     x0  0000006de705b3c0  x1  0000007010bf27cc  x2  0000006d877a78c0  x3  0000006d4a1e79a8
01-15 14:53:40.240 21741 21741 F DEBUG   :     x4  0000000000000018  x5  0000006d7727f17d  x6  3035343234303734  x7  0038303632303534
01-15 14:53:40.240 21741 21741 F DEBUG   :     x8  0000006ce0b67ef0  x9  00000000000000c0  x10 0000006d8702e000  x11 0000000000000030
01-15 14:53:40.240 21741 21741 F DEBUG   :     x12 000000000000000d  x13 000000008ea8faa7  x14 0000000000000030  x15 0000006d4a1e7844
01-15 14:53:40.240 21741 21741 F DEBUG   :     x16 0000006ce0b68670  x17 0000006ce0b60f50  x18 0000006bd3d32000  x19 00000000000054b8
01-15 14:53:40.240 21741 21741 F DEBUG   :     x20 0000006e2705af10  x21 0000006cc2dd7dd8  x22 0000006cc2dd7e20  x23 0000006cc2dcc644
01-15 14:53:40.240 21741 21741 F DEBUG   :     x24 0000006cc2dcc1bb  x25 0000006d877b0920  x26 0000006cc2dcc65f  x27 0000006cc2dcc051
01-15 14:53:40.240 21741 21741 F DEBUG   :     x28 0000006e170f73d0  x29 0000006d4a1e7a30
01-15 14:53:40.240 21741 21741 F DEBUG   :     lr  0000006cc2dcfb04  sp  0000006d4a1e7a10  pc  0000006cc2dcfb0c  pst 0000000060000000
01-15 14:53:40.240 21741 21741 F DEBUG   : backtrace:
01-15 14:53:40.240 21741 21741 F DEBUG   :       #00 pc 0000000000006b0c  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #01 pc 0000000000007adc  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #02 pc 0000000000007e98  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #03 pc 00000000000082f4  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #04 pc 00000000000530e8  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsutils.so (SyncHandle_Loop+324) (BuildId: b828e7b2f3db33f9445278f8a9016949763625a2)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #05 pc 00000000000b1910  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: ba489d4985c0cf173209da67405662f9)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #06 pc 00000000000513f0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: ba489d4985c0cf173209da67405662f9)

1 崩溃信息分析

1.1 头信息分析

从提供的崩溃信息头中,也就是这一部分:

01-15 14:53:40.240 21741 21741 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-15 14:53:40.240 21741 21741 F DEBUG   : Build fingerprint: 'Android/aosp_crosshatch/crosshatch:12/SP1A.210812.016.C1/eng.wangdsh.20221201.112332:userdebug/test-keys'
01-15 14:53:40.240 21741 21741 F DEBUG   : Revision: 'MP1.0'
01-15 14:53:40.240 21741 21741 F DEBUG   : ABI: 'arm64'
01-15 14:53:40.240 21741 21741 F DEBUG   : Timestamp: 2023-01-15 14:53:39.511121659+0800
01-15 14:53:40.240 21741 21741 F DEBUG   : Process uptime: 0s
01-15 14:53:40.240 21741 21741 F DEBUG   : Cmdline: com.ags.test
01-15 14:53:40.240 21741 21741 F DEBUG   : pid: 21179, tid: 21720, name: SL:21688_21707  >>> com.ags.test <<<
01-15 14:53:40.240 21741 21741 F DEBUG   : uid: 10356
01-15 14:53:40.240 21741 21741 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc0
01-15 14:53:40.240 21741 21741 F DEBUG   : Cause: null pointer dereference

我们可以得到以下基本信息:

  • 崩溃时间戳:崩溃发生的时间为 2023-01-15 14:53:39.511121659+0800。
  • 应用程序信息:应用程序的包名为 com.ags.test。
  • 进程信息:崩溃发生时的进程 ID 是 21179,线程 ID 是 21720,线程名称为 SL:21688_21707。
  • 设备信息:设备的 Build fingerprint 为 Android/aosp_crosshatch/crosshatch:12/SP1A.210812.016.C1/eng.wangdsh.20221201.112332:userdebug/test-keys,ABI 为 arm64。
  • 异常信息:崩溃原因是空指针解引用(null pointer dereference),信号为 11 (SIGSEGV),代码为 1 (SEGV_MAPERR)。崩溃地址为 0xc0。

1.2 寄存器信息分析

从提供的崩溃信息头中,也就是中间这一部分:

01-15 14:53:40.240 21741 21741 F DEBUG   :     x0  0000006de705b3c0  x1  0000007010bf27cc  x2  0000006d877a78c0  x3  0000006d4a1e79a8
01-15 14:53:40.240 21741 21741 F DEBUG   :     x4  0000000000000018  x5  0000006d7727f17d  x6  3035343234303734  x7  0038303632303534
01-15 14:53:40.240 21741 21741 F DEBUG   :     x8  0000006ce0b67ef0  x9  00000000000000c0  x10 0000006d8702e000  x11 0000000000000030
01-15 14:53:40.240 21741 21741 F DEBUG   :     x12 000000000000000d  x13 000000008ea8faa7  x14 0000000000000030  x15 0000006d4a1e7844
01-15 14:53:40.240 21741 21741 F DEBUG   :     x16 0000006ce0b68670  x17 0000006ce0b60f50  x18 0000006bd3d32000  x19 00000000000054b8
01-15 14:53:40.240 21741 21741 F DEBUG   :     x20 0000006e2705af10  x21 0000006cc2dd7dd8  x22 0000006cc2dd7e20  x23 0000006cc2dcc644
01-15 14:53:40.240 21741 21741 F DEBUG   :     x24 0000006cc2dcc1bb  x25 0000006d877b0920  x26 0000006cc2dcc65f  x27 0000006cc2dcc051
01-15 14:53:40.240 21741 21741 F DEBUG   :     x28 0000006e170f73d0  x29 0000006d4a1e7a30
01-15 14:53:40.240 21741 21741 F DEBUG   :     lr  0000006cc2dcfb04  sp  0000006d4a1e7a10  pc  0000006cc2dcfb0c  pst 0000000060000000

其中:

x0-x29分别表示30个寄存器。x0-x29 寄存器是 ARM64 架构中的通用寄存器,用于存储临时数据、函数参数或局部变量等信息。每个寄存器的命名以 x 开头,后面跟着一个数字。这些寄存器整体说明如下:

  • x0-x7: 这些寄存器用于存储函数参数和返回值。x0 是用于存储函数返回值的寄存器,而 x1-x7 用于传递函数参数。
  • x8-x15: 这些寄存器是用于存储临时变量的通用寄存器。它们可以被函数调用时保存和恢复,也可以用于存储中间计算结果。
  • x16-x18: 这些寄存器被称为「保留寄存器」,用于存储特定用途的值,如异常处理等。
  • x19-x28: 这些寄存器通常用于存储局部变量或保存调用者的寄存器状态。它们在函数调用时需要被保存和恢复,以确保函数的正确执行。
  • x29: x29 是帧指针(Frame Pointer),也称为 fp 或者 r29,用于指向当前函数的栈帧(stack frame)。栈帧包含了函数的局部变量、返回地址和其他与函数执行相关的信息。

这些寄存器在程序执行过程中起着关键的作用,用于存储数据、控制流程和传递参数等。它们的具体含义和使用方式可能会根据编程语言、编译器和操作系统的不同而有所差异。

最后一行,也是一组特殊的寄存器,这一组寄存器的含义解读如下:

  • lr: lr 代表链接寄存器(Link Register),也称为返回地址寄存器。它保存了将要执行的下一条指令的地址。在这里,lr 的值为 0000006cc2dcfb04,表示导致崩溃的指令的返回地址。
  • sp: sp 代表堆栈指针(Stack Pointer),指向当前线程堆栈的顶部。在这里,sp 的值为 0000006d4a1e7a10,指示了当前线程堆栈的顶部地址。
  • pc: pc 表示程序计数器(Program Counter),它存储了当前正在执行的指令的内存地址。在这里,pc 的值为 0000006cc2dcfb0c,指示了导致崩溃的指令的内存地址。
  • pst: pst 是指程序状态寄存器(Program Status Register)的值。它是一组用于记录处理器状态和控制处理器行为的位字段。在这里,pst 的值为 0000000060000000,具体的含义可能需要参考特定的处理器架构和指令集。

这些寄存器的值提供了关于崩溃发生时处理器状态的信息。它们对于分析崩溃原因和定位问题可能会有所帮助,但需要结合符号解析和其他调试信息来进行更深入的分析。

1.3 backtrace分析

接下来是我们查找错误中最好的入口,如下所示:

01-15 14:53:40.240 21741 21741 F DEBUG   : backtrace:
01-15 14:53:40.240 21741 21741 F DEBUG   :       #00 pc 0000000000006b0c  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #01 pc 0000000000007adc  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #02 pc 0000000000007e98  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #03 pc 00000000000082f4  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #04 pc 00000000000530e8  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsutils.so (SyncHandle_Loop+324) (BuildId: b828e7b2f3db33f9445278f8a9016949763625a2)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #05 pc 00000000000b1910  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: ba489d4985c0cf173209da67405662f9)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #06 pc 00000000000513f0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: ba489d4985c0cf173209da67405662f9)

根据这个backtrace 信息,可以看到它列出了导致崩溃的函数调用链。这些信息对于分析崩溃原因和定位问题非常有帮助。下面是对 backtrace 中主要内容的整体说明:

@1 libagsnetservice.so 中的函数调用链解读:

  • #00 pc 0000000000006b0c: 位于 libagsnetservice.so 库中的地址 0x6b0c 处的函数导致崩溃。
  • #01 pc 0000000000007adc: 位于 libagsnetservice.so 库中的地址 0x7adc 处的函数。
  • #02 pc 0000000000007e98: 位于 libagsnetservice.so 库中的地址 0x7e98 处的函数。
  • #03 pc 00000000000082f4: 位于 libagsnetservice.so 库中的地址 0x82f4 处的函数。

@2 libagsutils.so 中的函数调用链解读:

  • #04 pc 00000000000530e8: 位于 libagsutils.so 库中的地址 0x530e8 处的函数 SyncHandle_Loop 导致崩溃。

@3 libc.so 中的函数调用链:

  • #05 pc 00000000000b1910: 位于 libc.so 库中的地址 0xb1910 处的函数 __pthread_start 导致崩溃。
  • #06 pc 00000000000513f0: 位于 libc.so 库中的地址 0x513f0 处的函数 __start_thread。

这些函数调用链提供了导致崩溃的函数及其所在的库的信息,可以作为定位问题的起点。通过分析这些函数调用链,可以尝试确定导致崩溃的具体函数和库,以便进一步进行调试和修复。

那么怎么查看backtrace确定我们代码中哪一行出问题了呢,这就需要我们使用一些工具将 这些地址转换成具体的函数调用。接下来我们主要使用一些工具及具体的步骤来进行操作。

2 将地址转换成具体的函数调用的工具

2.1 addr2line工具

addr2line 是 GNU binutils 工具集中的一部分,用于将地址转换为源代码行号和函数名。它常用于调试和分析崩溃堆栈,以确定代码中出现问题的具体位置。addr2line 工具的主要功能是根据给定的可执行文件和地址,查找对应的源代码行号和函数名。它可以将机器代码地址映射到编译时生成的源代码位置,提供更具体的错误定位和调试信息。

使用 addr2line 工具进行地址转换的一般步骤如下:

@1 安装 GNU binutils:addr2line在Ubuntu 上可以运行以下命令来安装:

$sudo apt-get install binutils

@2 获取可执行文件和符号表文件:

确保有崩溃时生成的可执行文件(通常是APK或so文件)以及相应的符号表文件(.sym 文件)。符号表文件通常与可执行文件一起生成,并且应该与崩溃时的版本相匹配。

打开终端:打开终端或命令行界面,进入到包含可执行文件和符号表文件的目录。

@3 运行 addr2line 命令:

addr2line命令基本用法解读如下:

addr2line -f -e <可执行文件路径> <地址>

-f:显示完整的函数名和文件名。
-e:指定可执行文件的路径。
<地址>:要转换的地址,通常是崩溃堆栈中的地址。

例如,如果你的可执行文件名为 app.so,符号表文件名为 app.so,要转换的地址为 0x12345678,则命令如下:

$addr2line -f -e app.so 0x12345678

针对于该例子,针对0000000000006b0c地址,有:

$addr2line -f -e libagsnetservice.so -a 6b0c

以此类推,就可以得到完整的调用栈的错误了,也就将整个错误信息的地质值转换成代码错误的行数了。

@4 查看转换结果:

运行命令后,addr2line 将会输出对应地址的函数名和源代码行号信息,以及可能的内联函数信息。具体如下所示:

$addr2line -f -e libagsnetservice.so -a 6b0c
0x0000000000006b0c
_ZN4ags18NetServicer9startScanEi
/home/ags/test/core/.../NetService.cpp:473

可以根据这些信息来定位崩溃发生的具体代码行,以此类推,可以得到完整的崩溃栈信息。

注意:addr2line 工具适用于本地崩溃堆栈的地址转换,而不适用于远程崩溃报告。

2.2 ndk-stack

ndk-stack 是 Android NDK(Native Development Kit)提供的一个命令行工具,用于将崩溃堆栈中的地址转换为可读的函数和源代码行号信息。它是开发和调试 Android 应用程序时的有用工具之一。使用 ndk-stack 工具可以帮助开发者定位和分析发生在 Native 层的崩溃问题,例如 C/C++ 代码或使用 JNI(Java Native Interface)与 Java 层交互的代码。

使用 ndk-stack 工具的一般步骤如下:

@1 获取崩溃日志信息(说明:直接复制崩溃信息到crash.log也是可以的)。就是这个信息:

01-15 14:53:40.240 21741 21741 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-15 14:53:40.240 21741 21741 F DEBUG   : Build fingerprint: 'Android/aosp_crosshatch/crosshatch:12/SP1A.210812.016.C1/eng.wangdsh.20221201.112332:userdebug/test-keys'
01-15 14:53:40.240 21741 21741 F DEBUG   : Revision: 'MP1.0'
01-15 14:53:40.240 21741 21741 F DEBUG   : ABI: 'arm64'
01-15 14:53:40.240 21741 21741 F DEBUG   : Timestamp: 2023-01-15 14:53:39.511121659+0800
01-15 14:53:40.240 21741 21741 F DEBUG   : Process uptime: 0s
01-15 14:53:40.240 21741 21741 F DEBUG   : Cmdline: com.ags.test
01-15 14:53:40.240 21741 21741 F DEBUG   : pid: 21179, tid: 21720, name: SL:21688_21707  >>> com.ags.test <<<
01-15 14:53:40.240 21741 21741 F DEBUG   : uid: 10356
01-15 14:53:40.240 21741 21741 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc0
01-15 14:53:40.240 21741 21741 F DEBUG   : Cause: null pointer dereference
01-15 14:53:40.240 21741 21741 F DEBUG   :     x0  0000006de705b3c0  x1  0000007010bf27cc  x2  0000006d877a78c0  x3  0000006d4a1e79a8
01-15 14:53:40.240 21741 21741 F DEBUG   :     x4  0000000000000018  x5  0000006d7727f17d  x6  3035343234303734  x7  0038303632303534
01-15 14:53:40.240 21741 21741 F DEBUG   :     x8  0000006ce0b67ef0  x9  00000000000000c0  x10 0000006d8702e000  x11 0000000000000030
01-15 14:53:40.240 21741 21741 F DEBUG   :     x12 000000000000000d  x13 000000008ea8faa7  x14 0000000000000030  x15 0000006d4a1e7844
01-15 14:53:40.240 21741 21741 F DEBUG   :     x16 0000006ce0b68670  x17 0000006ce0b60f50  x18 0000006bd3d32000  x19 00000000000054b8
01-15 14:53:40.240 21741 21741 F DEBUG   :     x20 0000006e2705af10  x21 0000006cc2dd7dd8  x22 0000006cc2dd7e20  x23 0000006cc2dcc644
01-15 14:53:40.240 21741 21741 F DEBUG   :     x24 0000006cc2dcc1bb  x25 0000006d877b0920  x26 0000006cc2dcc65f  x27 0000006cc2dcc051
01-15 14:53:40.240 21741 21741 F DEBUG   :     x28 0000006e170f73d0  x29 0000006d4a1e7a30
01-15 14:53:40.240 21741 21741 F DEBUG   :     lr  0000006cc2dcfb04  sp  0000006d4a1e7a10  pc  0000006cc2dcfb0c  pst 0000000060000000
01-15 14:53:40.240 21741 21741 F DEBUG   : backtrace:
01-15 14:53:40.240 21741 21741 F DEBUG   :       #00 pc 0000000000006b0c  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #01 pc 0000000000007adc  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #02 pc 0000000000007e98  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #03 pc 00000000000082f4  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #04 pc 00000000000530e8  /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsutils.so (SyncHandle_Loop+324) (BuildId: b828e7b2f3db33f9445278f8a9016949763625a2)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #05 pc 00000000000b1910  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: ba489d4985c0cf173209da67405662f9)
01-15 14:53:40.240 21741 21741 F DEBUG   :       #06 pc 00000000000513f0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: ba489d4985c0cf173209da67405662f9)

@2 打开终端或命令行界面:

使用ndk-stack时候要注意:和编译app时使用的必须是同一个版本,一般在对应版本的android studio中的sdk目录中。找到自己对应的ndk版本,比如:~/Android/Sdk/ndk/23.0.7599858这种。直接进入到该目录下,后面直接使用该目录下的ndk-stack命令即可,不用再可以配置环境变量等。

@3 运行ndk-stack命令:

ndk-stack命令基本用法解读如下:

ndk-stack -sym <符号表目录>  -dump <日志文件路径>
-sym:指定包含符号表文件(.so 文件)的目录路径。

例如:如果你的crash信息在文件log2023.txt中,则可以:

$ndk-stack -sym path/to/your/symbols -dump log2023.txt

针对于该例子有:

$./ndk-stack -sym path/to/your/symbols  -dump  ./crash.log

其中 path/to/your/symbols 是包含符号表文件的目录路径。ndk-stack 将解析崩溃日志并输出转换后的堆栈跟踪信息,其中包含源代码行数。

@4 查看转换结果:

ndk-stack 将输出转换后的函数名和源代码行号信息,对应于崩溃堆栈中的地址。

$./ndk-stack -sym path/to/your/symbols  -dump  ./crash.log

运行后结果如下所示:

********** Crash dump: **********
Build fingerprint: 'Android/aosp_crosshatch/crosshatch:12/SP1A.210812.016.C1/eng.ags.20221201.112332:userdebug/test-keys'
#00 0x0000000000006b0c /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
ags::NetService::startScan(int)
/home/ags/.../NetService.cpp:473:21

#01 0x0000000000007adc /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
IPC_NetService_startScan /home/ags/.../NetServiceStub.cpp:27:45

#02 0x0000000000007e98 /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
IPC_NetService_startScan_Stub /home/ags/.../NetServiceStub.c:28:15

#03 0x00000000000082f4 /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsnetservice.so (BuildId: bf73aceda3d02c396e5e3ed10ccdd024f0b0ae2c)
IPC_NetService_Request_HandleFunc /home/ags/.../NetServiceStub.c:204:13

#04 0x00000000000530e8 /data/app/~~MMvSo__i24fnwmlXX8sFww==/com.ags.test-oDZ54tlfSncUOdIYkSEtWw==/lib/arm64/libagsutils.so (Handle_Loop+324) (BuildId: b828e7b2f3db33f9445278f8a9016949763625a2)
Handle_Loop /home/ags/.../IDL/EventLooper.c:258:17

#05 0x00000000000b1910 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: ba489d4985c0cf173209da67405662f9)
#06 0x00000000000513f0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: ba489d4985c0cf173209da67405662f9)
Crash dump is completed

通过分析ndk-stack的输出,开发者可以确定崩溃发生的具体函数和源代码行号,以及可能的调用栈信息,有助于定位和解决Native层的崩溃问题。实际上这里的一个完整的调用栈就出来了。

注意:ndk-stack 工具也是仅适用于 Native 层的崩溃堆栈转换。

11-16 06:22