如何解决gcc编译器优化导致的centos双编译器设置中的分段错误

How to resolve gcc compiler optimization-induced segmentation fault on centos dual compiler set up

本文关键字:编译器 centos 设置 错误 分段 优化 何解决 解决 gcc      更新时间:2023-10-16

我有一个用gcc构建的大型C++软件项目。在向存储库中添加一些新代码后,其中一个二进制文件开始在较大的测试数据上出现Segmentation Fault(在一些较小的测试输入上没有Segmentation(。我已经用两个不同的系统在几个不同的硬件上进行了测试。Ubuntu 18和Centos6。经过测试的GCC编译器分别为6.3、7.4和9.2。Ubuntu上的二进制构建总是好的,Centos上的二进制总是坏的(segfault(。操作系统出现问题:

uname -a
Linux hostname 3.10.0-957.27.2.el7.x86_64 #1 SMP Mon Jul 29 17:46:05 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux 

我的Unbuntu只有一个编译器,但Cenos通常有一个旧的gcc 4.8,除此之外,我们还构建了6.3、7.4或9.2。我的C++代码是用不同版本的gcc和不同的硬件构建的,所有这些都在上得到了segfault

std::ostream& operator(ostream&, const string&);

但来自我代码中几个随机位置中的一个。我使用了-O2或-O3选项。当使用-O0选项时,二进制文件没有问题,但速度慢了几倍。我正在尝试生成需要更快的生产代码。

我知道一个解决方案是找出哪行代码导致了这个分段错误,我下一步会尝试。我的问题是,在制作gcc编译器时,是否有任何选项可以帮助解决这个segfault问题?

我遵循了建议(在下面的评论部分提供(,打开了完整的警告,并用警告消息更新了所有依赖库(包括boost(。看起来这解决了问题。我学到了一个重要的教训:我们编写的任何代码都必须通过迂腐的Wall。应该有人写一个答案来帮助其他程序员。

没有其他人回答这个问题。我将在这里总结我的经验,没有任何具体的代码。首先,我在centos6上进行了测试,其中最初的gcc是4.8,我从gcc7.4构建了最新的gcc9.2编译器。在这台机器上,使用编译器9.2构建的二进制文件在使用-O选项时只有分段错误。segfault总是在stdostream&运算符<lt;(ostream&,conststring&(。在我检查了所有的代码和代码使用的所有库,并删除了所有警告之后,分段错误就消失了。我测试了大约一百个输入文件,所有文件都以退出状态0完成了程序。奇怪的是,分割错误最初只发生在我的cento6系统上。我的Ubuntu18即使在删除所有编译器警告消息和-O1-3选项之前也能正常工作。

我最近对我的代码做了一些小的更新,现在我开始在我的Ubuntu18(使用编译器gcc 7.4(上看到相同的分段错误。优化-g O1,O1,O2,O3都给出了分段错误-gO0生成的代码没有任何问题。现在Centos6可以进行任何优化。

由于分段故障位置在标准库中,调试运行不会显示任何关于错误原因的有用信息。剩下的唯一解决方案是注释掉不同的代码块,以定位哪段代码导致分段错误。这被证明是有用的。

在读取了导致分段错误的4行代码之后。我立刻意识到是哪条线路引起了麻烦:

// samearray is array<int,4> somearray;
somearray[4]=someNumber;

因此,当分段错误试图误导你去思考"编译器优化"、"不同的操作系统"、"不一样的编译器版本"时,要记住的是,抵制诱惑,坐下来通过一次注释块来消化你自己的代码。我仍然不知道为什么分段错误的发现与编译器优化选项有关。希望我的痛苦能帮助别人。