以debug标志运行时调试代码,但使用opt标志会导致段错误

4
我有一段 C++ 代码,在使用优化标志时会出现段错误,但在使用调试标志时不会。这使我无法使用调试器。除了连续的 cout 语句之外,是否还有其他方法/准则?
我正在 *nix 平台上使用 intel-12.1 编译器,我相当确定这是一个需要用 valgrind 捕获的内存问题。唯一让我困惑的是为什么它在调试模式下没有显示。

2
代码中有任何警告吗?这段代码是做什么的?通常情况下,这种情况发生在某种方式上依赖未定义行为(有时是由编译器错误引起的)。您通常可以使用调试信息和优化构建,以便获得符号,使调试器能够告诉您所在的函数以及代码何时被优化。 - Mats Petersson
1
你使用的平台和编译器是什么? - tristan
1
即使您进行优化,只要包括调试符号,您也应该能够大致了解错误的位置。除了加载核心转储文件之外,您还可以通过内存调试器(如Valgrind或clang-asan)运行程序,从而获得有关错误所在的线索。 - Kerrek SB
也许写更好的单元测试? - Kerrek SB
另外,您可以1. 注释掉代码的一部分,以定位问题。并且2. 检查与内存管理对应的代码部分,例如内存泄漏,以解决内存问题。但我猜您想问的是其他的工具? - klm123
1个回答

1

Valgrind是Unix系统的一个有用工具,用于调试发布模式的可执行文件(gflags和WinDebug对于Windows也很有用)。

我还建议不要放弃你的调试器 - 你可以在调试器中运行非调试可执行文件,仍然可以获得关于段错误的有用信息。通常情况下,即使开启了优化,你也可以添加一些调试信息,以提供更多上下文。你还可以检查一下英特尔编译器可能提供的任何调试模式堆检查功能,因为这些在调试构建中可能不会被检测到(由于不同的内存管理)。

此外,请注意通常有多个级别的优化可供您用于“发布模式”。你可以尝试降低到一个较少激进的优化级别,看看错误是否仍然发生。

你还可以查看英特尔编译器网站,看看是否有关于你正在使用的编译器版本的任何错误修复/错误报告方面的信息。

如果以上方法都没有帮助,你可以尝试使用另一种编译器(除非你正在使用某些特定于英特尔的东西),以查看问题是否与编译器相关。

最后,正如klm123所指出的那样,注释掉代码块是定位问题的好方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接