coredump 堆栈被写坏问题定位

coredump 堆栈被写坏问题定位

独家号 ftom 作者 ftom原文链接

问题描述

游戏后台有一个导号工具,主要是把外网玩家账号数据导入到内部环境供调试使用。 但是在导到有家族的账号的时候,脚本会core掉并且退出。 脚本运行是每次请求的时候拉起,执行完毕之后释放资源,无法在线进行gdb attach 上去断点看问题。


查问题第一步当然是尽可能的收集遇到的问题。 查看coredump 文件,bt堆栈如下所示:coredump 堆栈被写坏问题定位发生了Segment Fault 段错误,但是函数堆栈被写坏了 没有进一步可以帮助到的信息。


不过方法总比问题多。 我们可以在编译新的可执行文件时开启以下gcc 编译选项

  • -fstack-protector-all (https://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/index.html) 该选项旨在通过Canaries检测来判断栈是否被破坏,在破坏前让程序抛异常退出。 当然还有另外一个目的是提高栈溢出攻击的成本。有兴趣的可以了解下原理。通过这种方式来进行堆栈保护

  • -g 加上g选项后编译器会做如下额外操作
    • 创建符号表,生成的文件包含符号表内容。生成的core文件也会附带符号表相关内容
    • 关闭优化机制,程序严格按照原来的代码执行,避免定位问题对应代码带来的偏移干扰
  • 开启-O0 选项避免参数和函数inline。 生产环境建议开启为-O2 。这里为了方便定位问题,临时调整成该选项。

执行完上述步骤之后,采用新的二进制文件执行,程序coredump文件堆栈 如下所示:coredump 堆栈被写坏问题定位

出现_stack_chk_fail 毫无疑问是栈空间被写坏了。bt查看函数栈桢底部丢失,第#6函数桢丢失, 可以推断是上一桢函数把自己的返回地址搞丢了。可以重点排查下SaveTbFamily上 申请的栈变量以及内存拷贝赋值相关的代码


如果逻辑比较复杂,可以把该函数内申请的所有栈变量【主要是自定义类型】替换成堆变量。 再编一个版本出去,栈溢出可以肯定也能把对应的堆变量整溢出,堆溢出不至于把函数栈弄坏。

重新修改一个版本之后,重新执行获取到的core文件如下:coredump 堆栈被写坏问题定位这里终于借助堆溢出把完整的函数栈打印出来了。 接下来的事情就是常规的coredump问题定位了。


当然上述步骤仅限于在内网操作,如果是现网,最好隔离出一台机子,放少量流量进来复现。 定位问题不以要影响现网服务为首要原则 目前仅遇到上述场景,有其他好的方法,欢迎交流

扩展阅读:

定位 coredump  
上一篇:coredump产生的几种可能情况


下一篇:车联网解决方案、汽车CANBUS总线开发、车联网OBD、车载终端车联网平台研发设计、