本菜鸟写了一个server,经长时间激烈的测试以后,终于要在测试环境供外部使用了。经过一天激烈的打包,一枚rpm终于诞生了。上传到公司的yum包仓库,当PE同学部署时遇到了问题。程序在启动过程中莫名地core掉了,屡试不爽。使用gdb查看core文件的程序堆栈,发现程序core在了一个我从来没有修改过的类的析构函数中,core的直接原因就是C/C++程序员的老朋友Segmentation fault同学。查看该析构函数,里面只做了两个操作,简单讲,就是释放对象内存的两个delete。其中一个对象是在类的构造函数中创建,另外一个对象是在其他初始化函数startup中创建。析构函数中理所当然地对这两个对象的指针进行判断,非NULL则delete。这个类很特殊,正常情况下需要调用startup进行初始化,然后作为一个持久的对象使用。也可以不进行初始化,调用其他接口,然后销毁。我使用该类的场景就属于后者。在之前的测试过程中,core dump从未发生。
使用下面的代码简单地描述这个场景:
class FOO { public: FOO() { p = new Object; } ~FOO() { if (p) delete p; if (q) delete q; } void startup() { q = new Object; } private: Object *p; Object *q; }; int main() { FOO foo; return 0; }
看了这个程序,各位看官想必已经知道程序是怎么挂的了。但猫腻还不仅如此,这样编译运行该程序是没有问题的:
$ g++ test.cpp $ ./a.out
没有任何错误
$ g++ -O2 test.cpp $ ./a.out Segmentation fault(core dumped)
使用 -O2优化 宕掉了
调试该程序,查看它的汇编代码,会发现,没有使用优化选项的情况下,g++会初始化q为NULL,但在优化的情况下q就没有被初始化。
到这里,你可能会对C++的POD(Plain Old Data)感兴趣,但本文就不做展开了,以后有机会可能会介绍下。关于POD,可以参考这里,还有这里,作一个大致的了解。
江湖险恶,须谨言“慎行”。
转载请注明:爱开源 » g++ -O2 优化触发的bug