常用分析方法"/>
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后可一次追加多个地址
更多推荐
crash问题常用分析方法
发布评论