最新消息:

g++ -O2 优化触发的bug

bug admin 6100浏览 0评论

本菜鸟写了一个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

您必须 登录 才能发表评论!