【问题标题】:SIGSEGV in optimizated ifort优化 ifort 中的 SIGSEGV
【发布时间】:2013-01-21 21:15:03
【问题描述】:

如果我在 ifort 中使用 -O0 编译,程序可以正常运行。但是只要我打开优化选项,比如-O,-O3,-fast,就会出现SIGSEGV分段错误。

此错误发生在名为 maketable() 的子例程中。以下是现象:

(1) 我在这个子程序中调用了 fftw 库。如果我评论关于 fftw 的句子,就可以了。但我认为这不是fftw的错,因为我在这段代码的其他一些地方也使用了fftw,它们都很好。

(2) fftw在循环中被调用,当程序crash时循环可以运行多次。第一次进入循环时不会发生segfault。

(3) 我考虑过堆栈溢出,但我现在不这么认为。我有很久以前别人编译的可执行文件,可以在我的电脑上执行。我认为这表明这不是由于系统堆栈溢出。

ifort的版本是10.0,fftw的版本是fftw-2.1.5。 cpu类型是intel xeon 5130。非常感谢。

【问题讨论】:

  • 尝试在 valgrind 下运行您的代码。

标签: optimization segmentation-fault fftw intel-fortran


【解决方案1】:

Fortran 程序中出现分段错误的常见原因有两个:

  1. 试图访问数组边界之外的元素。
  2. 过程调用中的实际参数和虚拟参数不匹配。

两者都比较容易找到:

  1. 您的编译器可以选择生成在运行时执行数组边界检查的代码。检查您的编译器文档,重建您的代码并重新运行它。如果这是导致问题的原因,您将收到一条错误消息,指出您的代码出错的地方。
  2. 为程序中的任何子例程和函数编程显式接口,或使用模块以便编译器为您生成此类接口,或使用编译器选项(参见文档)在编译时检查参数类型是否匹配。

这种错误(似乎)仅在优化调高时才会出现,这并不罕见。

编辑

请注意,我并不是说优化会导致您观察到的错误,而是它会导致错误影响程序的执行并变得明显。

不正确的程序多次运行显然没有错误并不是未知的,例如,使用新的编译器版本重新编译以创建每次都崩溃的可执行文件。

我认为,您希望仅对似乎出现分段错误的子例程关闭优化,这是完全错误的。我希望我的程序在任何优化级别上都能正确执行(除了编译器错误的明确证据,这些事情并不未知)。我认为通过关闭优化,您实际上是在掩盖程序的真正问题。

【讨论】:

  • 是的,正如你所说。如果它超出了数组的范围,或者变量类型不匹配,那么在未优化的代码中也会出现问题。而且我确信这段代码很久以前就可以被其他人正确编译和执行。
  • 我仍然怀疑这是因为编译器优化。有什么办法可以保护这个子程序不被优化???我希望对所有其他部分进行优化编译,但不是这个子例程。我尝试 volatile 到子程序中的一些变量,但似乎没有帮助。
猜你喜欢
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多