coredump 堆栈被写坏问题定位

作者 ftom

问题描述

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


查问题第一步当然是尽可能的收集遇到的问题。 查看coredump 文件,bt堆栈如下所示:

android crash 堆栈信息 堆栈损坏怎么办_堆栈

发生了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文件堆栈 如下所示:

android crash 堆栈信息 堆栈损坏怎么办_堆栈_02

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


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

重新修改一个版本之后,重新执行获取到的core文件如下:

android crash 堆栈信息 堆栈损坏怎么办_bc_03

这里终于借助堆溢出把完整的函数栈打印出来了。 接下来的事情就是常规的coredump问题定位了。


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


GDB调试CoreDump出现??符号的解决方法


今天遇到个问题,某人的代码有断错误,导致我的工作无法展开,抱怨的就不多说了,正好让我解决了一个gdb的操作问题!

     现在说下gdb+coredump的调试流程

     在实机上先打开产生core文件的设置,ulimit -c unlimited  ,这将使程序在遇到断错误的时候保留下当时的堆栈信息,而这个core文件的大小没有进行限制,当然,还可以更改core文件的产生路径,具体可以google下。 之后运行断错误程序,获取产生的core文件。

     运用平台指定的gdb程序  调用arm-linux-gdb -c core    

      bt下

      这时会看到#0  0x2ae1cc9e in ?? ()之类的堆栈信息,因为没有指定带调试信息的调试程序,所以无法读书函数的符号表,所以显示不出当时的堆栈运行到那个函数。

      输入file exec ,显示出Reading symbols from /media/disk/work/ngi/work_space/ngi/out/target/product/high/system/usr/bin/testmode...done

     说明加载进了符号表,在bt下就应该能看到堆栈的函数名了

(gdb) bt
#0  0x2ae1cc9e in ?? ()
#1  0x2ac02600 in ?? ()
#2  0x2ac02600 in ?? ()

 

   奇怪 为什么还是没呢?  原来这时候程序是运行到动态库中去了,那既然如此当然需要把动态库中的符号表信息读入gdb咯!

 

    事实是否如我猜测呢?

    输入info share

 

(gdb) info share
warning: .dynamic section for "/media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/libm.so.6" is not at the expected address (wrong library or version mismatch?)
warning: .dynamic section for "/media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/libc.so.6" is not at the expected address (wrong library or version mismatch?)
warning: Could not load shared library symbols for 60 libraries, e.g. /lib/libncore.so.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
From       To         Syms Read   Shared Object Library
                     No         /lib/libncore.so
                     No         /lib/libicuuc.so
                     No         /lib/liblog.so
                     No         /lib/libncutility.so
                     No        /lib/libncplatform.so
                     No         /lib/libncdevice.so
                     No         /lib/libnhcommon.so
                     No         /lib/libnhdiag.so
                     No         /lib/libnhucom.so
                     No         /lib/libnhkey.so
                     No         /lib/libnhsysctrl.so
                     No         /lib/libzeromq.so
                     No         /lib/libbinder.so
                     No        /lib/libnceventsys.so
                     No        /usr/lib/libncgstreamer.so
                     No         /lib/libGLESv1_CM.so
                     No         /lib/libEGL.so
                     No         /lib/libGAL.so
                     No        /usr/lib/libncgraphics.so
                     No        /usr/lib/libGraphicsCore.so
                     No        /usr/lib/liboverlay.so
                     No         /usr/lib/libtuner.so
                     No        /usr/lib/libsourceusbapi.so
                     No        /usr/lib/libsourceusb.so
                     No        /usr/lib/libnhbtproxy.so
                     No         /usr/lib/libgmock.so
                     No         /lib/libncstorage.so
                     No         /lib/libnhvehicle.so
                     No         /lib/libnhcanbus.so
0x2ae83e80  0x2ae91fdc  No        /media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/libpthread.so.0
0x2adb56a0  0x2adb8e58  No        /media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/librt.so.1
0x2adc38fc  0x2adc4614  No        /media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/libdl.so.2
                     No         /lib/libstdc++.so.6
0x2b0f61a8  0x2b15a9b8  No        /media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/libm.so.6
                     No         /lib/libgcc_s.so.1
0x2b179440  0x2b262044  No        /media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/libc.so.6
0x2aaef780  0x2ab07a20  No        /media/disk/work/ngi/work_space/ngi/prebuilts/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/lib/ld-linux.so.3
                     No         /lib/libutils.so

    可以看到很多库的符号表都没有被读入,看来果然如此。

    输入用set solib-search-path + 库的路径 指定所要读取的符号表动态库所在位置,结果会看到很多done之类的信息,说明加载成功,  

    现在bt下就能看到堆栈的详细信息了。

   

(gdb) bt
#0  nutshell::SourceUSB_ScannerThread::setScannerState (this=0x0, 
   state=nutshell::SourceUSB_ScannerThread::SCANNERSTATE_START)
    at system/MediaLibrary/SourceUSB/src/Thread_Scanner/SourceUSB_ScannerThread.cpp:138
#1  0x2ae1ce1a in nutshell::SourceUSB_Scanner_EventHandler::onHandle (this=0xaf4a0, cEvt=...)
    at system/MediaLibrary/SourceUSB/src/Thread_Scanner/SourceUSB_Scanner_EventHandler.cpp:50
#2  0x2ae17018 in nutshell::SourceUSB_EventHandlerBase::onHandle (this=, cEvt=)
    at system/MediaLibrary/SourceUSB/src/include/base/SourceUSB_EventHandlerBase.h:35
#3  0x2abe85b6 in nutshell::PI_EventHandlerThreadImp::run (this=0xaef88)
    at system/MediaLibrary/common/TsmThreadLib/src/PI_EventHandlerThreadImp.cpp:93
#4  0x2ac04e34 in ?? ()
#5  0x2ac04e34 in ?? ()

 

之后就是去告诉某人这个问题所在了 

 

没有core堆栈