美文网首页
一次意外的core

一次意外的core

作者: fooboo | 来源:发表于2016-03-12 23:50 被阅读80次

    最近比较忙,二十二点下班,周六要加班。这里只记录工作中遇到的问题和解决思路,不会设计具体的代码,作为公司员工,还是要遵守基本职业道德的。

    事情是这样的,我负责的是装备模块,另外一位同事A在里面加了个套装,几十行代码。我很早就在与数据库有关的.xml文件中定义了个类似宏MAX_EQUIP_SIZE的字段,大小是10。然后同事A在某个头文件中定义了个数MAX_EQUIP_SIZE/2=5的数组,在其他几个源文件中代码处使用的是MAX_EQUIP_SIZE/2。由于玩家数据是放在共享内存中的,如果使用STL相关的组件在热启时会有问题【分配内存是在堆】。然后A同事在操作套装时循环次数是是MAX_EQUIP_SIZE/2,但在某个初始化Init接口中是MAX_EQUIP_SIZE,后来导致了core,也产生了800MB+的文件,gdb跟了一下,是宕在了CObj.Clear(),SIGNAL 11,经分析后,该对象不可能为空,因为CObj类的实例也是作为玩家对象的一个成员,而套装数组是作为CObj类的一个data member。

    猜想很可能是数组越界访问了非法地址,后来需要查看汇编才能知道到底出问题是在哪行代码。使用dmesg tail查看对应进程core在了哪个ip地址,假设ip = AAAAA,根据可执行文件objdump -d YourProgramName可以看出AAAAA对应的汇编代码。AAAAA        movl  88(%rax), xxxx具体的忘了,反正就是对某个地址加了88个字节的偏移量,问题就出在这里了,然后仔细对照着源程序分析这一段汇编代码,发现在Init中初始化该数组时的大小不是定义该数组时的大小。后来让A同事修改了,定义一个大小是5的宏,文件中使用他,而不是使用MAX_EQUIP_SIZE/2,因为很可能会忘记除以2造成不一定性和程序的未定义行为。【addr2line -e YourProgramName AAAAA -f 查看具体出问题的代码行】

    前几天看了蘑菇街的TeamTalk的一些代码,发现有些类并不作为派生类的基类,也即不被继承,也有虚函数,只不过是虚析构【为了在被继承时正确释放资源以免造成资源泄露】。记得在Effective C++中专门有一节内容讲类似内容的。这个有点多余了,声明了虚函数,就得有个虚函数表,和每个对象有个虚函数指指针指向该虚函数表,一来增加了每个对象的大小【在不同的架构上指针大小4字节或8字节】,二是编译器会为每个类的构造函数扩张构造函数以正确设定虚函数指针和其他,此时如果用户定义的构造函数不是默认构造函数或者压根没有构造函数,那么编译器为我们生成一个默认构造函数【在编译器看来只做它做的事】,初始化与虚函数相关的东西,也会扩张非默认构造函数等等.....

    相关文章

      网友评论

          本文标题:一次意外的core

          本文链接:https://www.haomeiwen.com/subject/oiwxlttx.html