我正在开发一个嵌入式Linux系统(5.10.24),其中运行着几个应用程序。
最近,我发现一个 C 程序有些奇怪。
该 C 程序使用了 SDK 库提供的 API,该 SDK 是用 GNU 构建的-O2
,但默认情况下该 C 程序是用 GNU 构建的-O3
。
然后发现有时(运行数百次中就有一次)C 程序会Segmentation Fault
在 SDK 中的某个函数中触发。
如果 C 程序使用与 SDK 相同的 GNU 构建,则在其数千次运行中-O2
不会触发此类事件。Segmentation Fault
-O2
我在 Google 上搜索了和的区别-O3
,发现有人提到这-O3
可能会引发奇怪而有趣的错误,是真的吗?
一般而言,假设数百万人使用的主流软件运行正常,而您自己刚刚开发并仅供您使用的软件是问题的根源。 在开发人员的职业生涯中,像这样在 GCC 中发现真正的错误是极其罕见的,有点像中彩票。根据组织和用户群的规模以及产品的使用年限,在闭源专有代码中发现错误更为常见。
优化不会影响预编译的代码,只会影响使用 GCC 编译的代码。
优化级别是添加一大堆优化标志的简写。您可以单独试验它们,看看哪一个会导致问题。例如
-O3
:通常情况下,代码和 API 之间的优化级别不匹配不会造成问题。调用约定不受影响。在极少数情况下,
struct
填充可能会错位,但这种情况很少见。更常见的是,优化会做以下两件事之一:
volatile
正确使用诸如 C 之类的关键字造成的。-O3
over的优化会删除填充-O2
。它可能仍会重新排序,使得现有的缓冲区溢出或数组索引错误现在会导致致命错误,而原来不会。我没有看到您所读内容的上下文,但总的来说,假设优化代码会触发代码中的错误,而不是编译器中的错误。
这确实是事实,并且可能表明存在 GCC 问题。
如果您的 SDK 是开源的,并且您使用的是受支持的 GCC 版本之一,则可以提交错误报告。否则,降低优化级别才是最佳选择。