欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记录一次内存错误排查过程

程序员文章站 2022-07-15 07:58:32
...

问题现象

一个播放器的实现代码,在多次播放后,出现异常挂死,gdb显示如下图

记录一次内存错误排查过程

通过bt命令查看函数调用栈,只有一条有效消息,就是  “#3 0xa0”  这个地址明显是错误的。所有怀疑是栈被破坏了。 

直接报错内容也是多种多样。以下这些错误都出现过。

double free or corruption (!prev)
corrupted size vs. prev_size
double free or corruption (out)
malloc(): memory corruption (fast)
double free or corruption (fasttop)
glibc detected *** free(): invalid next size (normal)

定位过程

  1. 根据log信息或者注释部分代码的方式来收敛错误范围。
  2. 打印关键变量地址,复现问题,进一步所有排查范围。
  3. 经过仔细核对关键变量地址的变化,定位到面代码。记录一次内存错误排查过程
  4. 前后地址不一致,中间部分代码又跟被修改变量不相关。
  5. 仔细检查链表操作代码,没有问题。
  6. 然后根据这部分里面其他函数调用,及相关逻辑进行检查,发现player播放完成后任务被销毁,但是没有从链表中删除任务节点。
  7. 修正之后,再没有出现问题。

总结

  • 通过最开始报的各种错误集gdb看到的调用栈中异常地址,大致判断是栈被破坏或者出现使用野指针的问题。所以内存使用就乱了,关于内存报错的信息也是千奇百怪。
  • 关于内存错误的问题,多数是内存地址被踩,可以根据关键变量地址被修改来缩小查找范围。当然,如果只有log,没有条件去重新运行复现问题,就只能推测,仔细检查代码。