只有在使用Intel Visual Fortran编译时,子程序调用上的堆栈溢出,并且当由Compaq Visual Fortran编译时才会很好

时间:2012-04-13 19:20:46

标签: arguments fortran intel-fortran

使用Fortran .dll的相同源文件,我可以使用Compaq Visual Fortran 6.6C或Intel Visual Fortran 12.1.3.300(IA-32)编译它们。问题是英特尔二进制文件的执行失败,但与Compaq一起运行良好。我正在Windows 7 64位系统上编译32位。 .dll调用驱动程序是用C#编写的。

当调用内部子例程(从.dll入口例程调用)时,失败消息来自可怕的_chkstk()调用。 (回答chkstk()

有问题的程序被声明为(原谅固定文件格式)

  SUBROUTINE SRF(den, crpm, icrpm, inose, qeff, rev,  
 &               qqmax, lvtyp1, lvtyp2, avespd, fridry, luin,  
 &               luout, lurtpo, ludiag, ndiag, n, nzdepth, 
 &               unit, unito, ier)

  INTEGER*4 lvtyp1, lvtyp2, luin, luout, lurtpo, ludiag, ndiag, n, 
 &          ncp, inose, icrpm, ier, nzdepth
  REAL*8    den, crpm, qeff, rev, qqmax, avespd, fridry           
  CHARACTER*2  unit, unito

并且这样调用:

      CALL SRF(den, crpm(i), i, inose, qeff(i), rev(i),  
 &             qqmax(i), lvtyp1, lvtyp2, avespd, fridry, 
 &             luin, luout, lurtpo, ludiag, ndiag, n, nzdepth,  
 &             unit, unito, ier)
除了crpmqeffrevqqmax之外,

具有类似的变量规范是每个{{{}仅使用i-th个元素的数组1}}来电。

如果参数的大小超过SRF(),我理解可能的堆栈问题,但在这种情况下,我们只在传递的参数中有8kb

我已经非常努力地将参数(尤其是数组)移动到模块中,但我一直得到同样的错误

error

来自 Intel .dll的解散

intel

来自 Compaq .dll的组件

compaq

任何人都可以就导致SO的原因或如何调试提供任何建议吗?

PS。我已将保留的堆栈空间增加到数百7 x real(64) + 11 x int(32) + 2 x 2 x char(8) = 832 bits,问题仍然存在。我试过跳过dissasembler中的Mb调用但是崩溃了程序。堆栈检查从地址chkstk()开始,并向下迭代到0x354000,在那里崩溃访问保护页面。堆栈底部地址为0x2D2000

2 个答案:

答案 0 :(得分:3)

你正在射击信使。 Compaq生成的代码调用_chkstk(),区别在于它内联它。一个常见的优化。两个片段之间的主要区别是:

 mov eax, 0D3668h

VS

 sub esp, 233E4h

您在此处看到的值是函数所需的堆栈空间量。英特尔代码需要0xd3668字节= 865869字节。 Compaq代码需要0x233e4 = 144356.差异很大。在这两种情况下,相当大的数量,但英特尔正在变得越来越重要,一个程序通常有一个兆字节的堆栈。吞噬它的0.86兆字节非常接近,嵌入了几个函数调用,你正在看这个网站的名字。

您需要了解的内容,我无法提供帮助,因为它不在您的代码段中,这就是英特尔生成的函数需要为其局部变量提供如此大空间的原因。解决方法是使用免费存储来查找大型数组的空间。或者使用链接器的/ STACK选项来请求更多的堆栈空间(猜测选项名称)。

答案 1 :(得分:0)

问题不在于发生堆栈溢出的函数调用。

在代码的早期,有一些全局矩阵被初始化并被放置在堆栈中,由于代码中的错误,它们仍然在范围内并且已经几乎填满了堆栈。当函数调用发生时,编译器试图将返回地址存储到堆栈中,结果导致程序崩溃。

解决方案是使全局矩阵 allocatable 并确保“堆数组”选项设置为适当的值。

这真是个兔子洞,当 100% 是我的错误代码导致了问题。