• 诊断Android系统原生代码Native崩溃问题


    诊断原生代码Native崩溃问题

    Abort(中止操作)

    log信息signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr。代码中Abort中止操作为刻意为之。执行中止操作可通过多种不同的方法(包括调用 abort(3)、使 assert(3) 失败、使用 Android 特有的严重记录类型)来实现,所有方法都调用到 abort。abort 调用会向发起调用的线程发出 SIGABRT 信号,因此在log中,libc.so 中显示“abort”的帧,以及 SIGABRT 信号。
    参考示例如下(部分日志):

    pid: 4637, tid: 4637, name: crasher >>> crasher <<<
    signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
    Abort message: ‘some_file.c:123: some_function: assertion “false” failed’
    r0 00000000 r1 0000121d r2 00000006 r3 00000008
    r4 0000121d r5 0000121d r6 ffb44a1c r7 0000010c
    r8 00000000 r9 00000000 r10 00000000 r11 00000000
    ip ffb44c20 sp ffb44a08 lr eace2b0b pc eace2b16
    backtrace:
    #00 pc 0001cb16 /system/lib/libc.so (abort+57)
    #01 pc 0001cd8f /system/lib/libc.so (__assert2+22)
    #02 pc 00001531 /system/bin/crasher (do_action+764)
    #03 pc 00002301 /system/bin/crasher (main+68)
    #04 pc 0008a809 /system/lib/libc.so (__libc_init+48)
    #05 pc 00001097 /system/bin/crasher (_start_main+38)
    ···中止相关代码信息省略

    在log中一般会看到明确的中止信息,了解此线程在刻意终止自身之前所记录的内容。追踪Native调用栈,返回追查定位问题。
    android系统native层代码中存在一些判断逻辑进行abort,不一定是native层的问题,可能存在上层App触发了错误的逻辑。

    Null空指针

    分为纯空指针和低地址空指针,log信息为signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
    纯空指针引用示例如下:

    pid: 25326, tid: 25326, name: crasher >>> crasher <<<
    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    r0 00000000 r1 00000000 r2 00004c00 r3 00000000
    r4 ab088071 r5 fff92b34 r6 00000002 r7 fff92b40
    r8 00000000 r9 00000000 sl 00000000 fp fff92b2c
    ip ab08cfc4 sp fff92a08 lr ab087a93 pc efb78988 cpsr 600d0030
    backtrace:
    #00 pc 00019988 /system/lib/libc.so (strlen+71)
    #01 pc 00001a8f /system/xbin/crasher (strlen_null+22)
    #02 pc 000017cd /system/xbin/crasher (do_action+948)
    #03 pc 000020d5 /system/xbin/crasher (main+100)
    #04 pc 000177a1 /system/lib/libc.so (__libc_init+48)
    #05 pc 000010e4 /system/xbin/crasher (_start+96)

    在上面示例中,尽管崩溃函数在 libc.so 内,但由于字符串函数仅在指定给它们的指针处进行操作,因此您可以推断出在调用 strlen(3) 时指定的是 Null 指针;对于这类崩溃问题,应直接找发起调用的代码的作者加以解决。在这种情况下,帧 #01 是不良调用程序。

    *低地址 Null 空指针引用和更多信号奔溃问题详见诊断原生代码崩溃问题

    Linux中32个信号及其含义

    Arch Linux发行版中,有着arch/usr/include/asm/signal.h这样的头文件,定义Linux系统中信号类型。Linux中32个信号及其含义如下:

    信号含义
    #define SIGHUP 1终端挂起或控制进程终止
    #define SIGINT 2终端中断(Ctrl+C 组合键)
    #define SIGQUIT 3终端退出(Ctrl+\组合键)
    #define SIGILL 4非法指令
    #define SIGTRAP 5debug 使用,有断点指令产生
    #define SIGABRT 6由 abort(3)发出的退出指令
    #define SIGIOT 6IOT 指令
    #define SIGBUS 7总线错误
    #define SIGFPE 8浮点运算错误
    #define SIGKILL 9杀死、终止进程
    #define SIGUSR1 10用户自定义信号 1
    #define SIGSEGV 11段违例(无效的内存段)
    #define SIGUSR2 12用户自定义信号 2
    #define SIGPIPE 13向非读管道写入数据
    #define SIGALRM 14闹钟
    #define SIGTERM 15软件终止
    #define SIGSTKFLT 16栈异常
    #define SIGCHLD 17子进程结束
    #define SIGCONT 18进程继续
    #define SIGSTOP 19停止进程的执行,只是暂停
    #define SIGTSTP 20停止进程的运行(Ctrl+Z 组合键)
    #define SIGTTIN 21后台进程需要从终端读取数据
    #define SIGTTOU 22后台进程需要向终端写数据
    #define SIGURG 23有"紧急"数据
    #define SIGXCPU 24超过 CPU 资源限制
    #define SIGXFSZ 25文件大小超额
    #define SIGVTALRM 26虚拟时钟信号
    #define SIGPROF 27时钟信号描述
    #define SIGWINCH 28窗口大小改变
    #define SIGIO 29可以进行输入/输出操作
    #define SIGPOLLSIGIO
    #define SIGPWR 30断点重启
    #define SIGSYS 31非法的系统调用
    #define SIGUNUSED 32未使用信号

    参考博客:Linux中32个信号及其含义Android native crash 信号量signal对应的含义
    32种信号同样适用于Android系统。

  • 相关阅读:
    图片扫描仪第一弹,我实现了一个办公位简笔画
    [ruby on rails] pg触发器trigger的使用
    SAP 电商云 Spartacus UI Angular UI 和 Accelerator JSP UI 的混合使用
    mybatis-拦截器实际应用-替换表名-2022新项目
    Connor学JVM - 垃圾收集器
    Java类和对象:类是对象的模板,对象是类的实例化
    JQuery对Dom的支持
    激光雷达:自动驾驶的眼睛
    深入浅出详解Knative云函数框架!
    Rancher清理节点
  • 原文地址:https://blog.csdn.net/CJohn1994/article/details/126590240