稳定性专题

凡是崩溃问题,都要面对崩溃调用栈

1. 调用栈,从高地址到低地址发展

2.每个线程对应一个独立的调用栈

3.tls线程本地存储,也是存储在调用栈上

4. linux上栈大小默认8M,创建线程时候可以指定

5. gcc参数-fno-omit-frame-pointer和-fomit-frame-pointer,前者有push rbp指针,后者无,并且默认无,也就是说靠程序和栈数据一起计算栈帧长度,才能展开调用栈

6. 如果栈数组越界,有可能踩坏返回地址,导致调用栈无法展开

7. 如果动态库释放了,无法解析栈中局部变量,导致调用栈无法展开

 

常见的踩内存分类:

1. 库释放

动态库释放后,还在执行其程序,导致的崩溃

2. 栈踩坏

函数调用栈被踩坏,导致的崩溃

3. 堆踩坏

进程堆空间被踩坏,导致的崩溃

还有全局区踩内存,不常见

 

 崩溃栈几乎为空,仅f0地址“0x00007f4dc41b39e2”

dmesg有error 14,其二进制为0b1110表示,用户态程序写无效内存地址导致崩溃

 

分析:1. 该地址是代码段地址,理应属于某个so库,但是现在为空,可能是已经释放

2. dmesg的error含义如下:

bit2:值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界

bit1:值为1表示写操作内存导致内存访问越界,值为0表示是读操作导致内存访问越界

bit0:值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面(也就是无效地址)

3. 退出会释放库,正好吻合判断

总之,大概率为库释放后,还在执行他里面的函数,导致进程崩溃:

既然崩溃时候,库已经释放了,那就在崩溃前,把进程的文件映射表保存下来,供找库使用,找到对应库(有映射起始和结束地址),可计算崩溃地址相对于so的偏移,进而找到具体的代码行号。

 退出前保存文件映射表(执行命令 cat /proc/进程PID/maps > maps.txt)

崩溃地址7f88581b39e2属于libSecurityKeyManager.so的代码范围

崩溃地址减去代码段起始地址:0x7f88581b39e2 - 0x7f8858197000 = 0x1c9e2

执行 addr2line -e libSecurityKeyManager.so 0x1c9e2

结论,mgc进程退出时,libSecurityKeyManager.so库都已经释放了,但是其线程没有停止,故崩溃。

 栈踩坏崩溃

1. 当前64位CPU架构,指针只有48bit,所以只有前3帧(f0,f1,f2)地址为代码段地址,后面都是错误的指针

2. 调用栈帧指针为返回地址,所以栈上返回地址被踩坏

3. 调用栈从高地址向低地址发展,另外越界一般从低地址向高地址越,故前几帧(f0, f1, f2)是正常的,未被踩坏,查看f2代码,发现数组越界

 

总结:

堆踩坏表现为乱崩,常见new malloc delete free 等系统函数崩溃

简单场景(运气好),崩溃的调用栈就是踩坏的调用栈,释放的内存快被踩坏则free崩溃

疑难场景,新申请内存,正好申请到与踩坏内存有交叉,则malloc崩溃,无法捕捉堆踩坏的第一现场,需要asan定位

 

asan原理概要

编译期

1. 给栈变量和全局变量,添加头和尾保护区

2. 对变量的读和写访问,插入合法性检测代码

运行期

1. 给动态申请内存,添加头和尾保护区

2. 维护影子区的状态信息

3. 在变量读和写访问前,依据影子区状态,检查访问是否合法

 

1. 前后保护区,用于越界访问检查

2. 影子内存记录内存状态,64位系统,一般最大内存256T,每16Byte用1Byte影子区标记,故影子区最大256T/16=16T

3. 1Byte影子区记录16Byte内存区连续使用字节数及其他状态信息,1Byte可以表示256种状态,而16Byte连续字节数仅为17中状态,故还可以表示其他239中状态,如已释放、未分配等绰绰有余。

 

asan工具,期望进程加载的所有库都asan编译,这对我们不现实

1. 应对规则,保证“未asan的内存”不给“已经asan的源码”使用,因为“已经asan的源码”访问内存,会要求有头尾保护区和影子区标记,结果没有就崩溃

2. 应对思路:找到一个混合子集,仅asan编译子集中的库和源文件即可

3. 应对方法:依据崩溃栈和相关业务,找一个初始子集编译asan,如果启动崩溃,依据业务扩大或缩小子集范围,如此循环,直到启动成功,业务能正常运行

不现实的原因:

1. 有些动态库,我们没有源码 2. 进程加载库太多,全部编译或推动库负责人编译工作量和工期太大

 

posted @   大大大龙  阅读(79)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示