crash问题常用分析方法

文章目录

    • 主导问题
    • 方法1:addr2line
    • 方法2:反汇编objdump
    • 方法3:Asan(address sanitizer)

主导问题

  • 什么是crash?
    • 代码异常导致进程退出的现象
  • 为什么会crash?
    • 访问堆、栈上的异常地址
  • 平时调试或者客户端遇到crash问题,如何分析,是否有具体的方法?
    • 目前常用的有三种分析手段

方法1:addr2line

  • 什么是addr2line?

    • “address to line”的缩写,功能是通过可执行文件中的地址,使用调试信息解析出与地址对应的文件名、函数名和行号。
    • **前提是:**执行程序编译时包含调试信息(-g)
  • 语法格式

    • addr2line [参数] [地址]
  • 参考实例

static int debug_test(void)
{
    int8_t *buf = NULL;
    printf("[%s] before crash, buf=%p", __func__, buf);
    *buf = 100;
    printf("[%s] after crash", __func__);
    return 0;
}
  • crash日志

    • 待补充
  • addr2line分析

    • 注意:需使用包含调试信息的二进制文件来查看

方法2:反汇编objdump

  • 什么是objdump?

    • objdump是查看目标文件构成的gcc工具
  • 语法格式

    • objdump [参数] [文件]
    • 参数-S:混合显示源码和汇编代码
    • 参数-D:反汇编所有section
  • 参考实例

    • 参考方法1实例
  • crash日志

    • 参考方法1日志
  • objdump分析

    • 注意:objdump需用编译工具链下的objdump,不能用系统自带的,否则会反汇编失败。

方法3:Asan(address sanitizer)

  • 什么是Asan?

    • Google 发明了Address Sanitizer, 是一种地址错误检查器,这个东西在运行时发挥作用
    • 程序申请的每 8bytes 内存映射到 1byte 的 shadown 内存上。
    • asan还会在程序申请的内存的前后,各增加一个redzone区域(n * 8bytes),用来解决overflow/underflow类问题
  • 使用限制

    • Address Sanitizer是运行时的能力,代码只有被运行到了才能检测出内存问题,而我们无法保证所有的代码分支和逻辑都能执行到,所以检测并不是全面的。
    • 环境要求:在使用ASan时,你需要使用Clang编译器和LLVM工具链。具体来说,你需要下载和安装具有ASan支持的Clang编译器。
  • 缺点

    • 开启Address Sanitizer,将使代码执行效率降低2-5倍,内存使用增加2-3倍
  • Address Sanitizer可以用来检测如下内存使用错误:

    • 内存释放后又被使用;
    • 内存重复释放;
    • 释放未申请的内存;
    • 使用栈内存作为函数返回值;
    • 使用了超出作用域的栈内存;
    • 内存越界访问;
  • 参考实例

int debug_test(void)
{
    char b[5] = { 0 };
    printf("[%s] before crash", __func__);
    cpl_memset(b, 6, 10);
    printf("[%s] after crash", __func__);
    return 0;
}
  • crash日志

    • 待补充
  • Asan分析

    • addr2line命令解析可执行程序偏移量(+0x10998b +0x1be6df +0x11ba2f),addr2line后可一次追加多个地址

你可能感兴趣的:(1024程序员节,经验分享,linux,c语言)