我有一个在 Windows 7 下使用 Intel fortran 编译器 2013 和 VS2010 编译的 fortran 代码,它开始给我未处理的异常,而没有显示代码崩溃的行。通常会出现这样的错误:
Unhandled exception at 0x73e1d3d2 in GRIB2METEOriparto.exe: 0xC0000005: Access violation writing location 0x00240ef4....
并且调用堆栈只有 dbghelp.dll 或 verify.dll 并且没有可用的源。我在 Cygwin 下移动了我的源文件,我用 gfortran 编译了所有可能的警告/错误标志(包括检查边界和隐式接口)并且根本没有警告并且程序运行顺利。所有接口都是明确的,因为我使用的是“CONTAINS”。因此,如果参数数量不匹配,调试器会捕获它。不存在未初始化的变量。我回到VS2010,我做了一个“干净的解决方案”,我重建了项目。代码开始在不同的 C 例程(我没有编写)中崩溃,例如:
crt0.c at the line:
mainret = _tmain(__argc, _targv, _tenviron);
或者
osinfo.c at line (if I well remember):
EnterCriticalSection( &(_pioinfo(fh)->lock) );
代码甚至没有到达可执行代码的第一行(没有到达断点)。
我开始评论我最近在过去几天添加的一些代码行,并且在运行线程时终于成功通过了前几行,它在子例程调用中崩溃并出现 stackoverflow 错误。这终于帮助我理解了这个问题。我有一堆被声明为 character*2560 的字符(在子程序和主代码中)。我用 character*256 替换了它们,它不再崩溃了。我重写了 character*2560 并在链接选项中添加了标志 /stack:2000000 ,现在一切运行顺利。我删除了我在那些代码行中添加的额外注释(在其中调用具有太多字符 * 2560 的错误子例程)并且一切运行顺利。我在 Cygwin 中用 gfortran 重新编译了所有东西,一切都很好。这是正常的吗?我现在安全了吗?最初堆栈溢出错误是否由于某种原因被错误地解释为访问冲突?那可能吗?
编辑:这是我在主程序中的错误声明(我在其他子程序中有类似的声明(但更短)):
character*2560 DOScallINV,FORMdosCALLtxt,FORMdosCALLinv,filenam,FILEinv,provSTR,FMTtimeMETEO,&
TIMEstring,fmtGRID,fmtTIMEstring,FMTdataMETEO,WORKINGdir,path,DIRgribs,PATHgribs,&
DIRresultsRUN,PATHoutput,previousDIR,filePATH,PATHresultsRUN,PATHinputD3D,textFILE,&
newLINE,textFILE1,textFILE2,PATHlogs,LOGfile,LOGdir,ilineTXT,message,PATHresultsREST,&
LastRUNfolder,PATHobs,PATHopenda,PATHresultsRUNm1,workworkWITHnum,pathSTOBS,pathSTMOD,pathALG,&
toBEfound,COLLECTdirect,COLLECTdirectLOC,PATHwork,filePATHtot,filePATHlong,stringCAL,string,&
pathNM,filePATH_d3model,CDstring,toBEadded,stringCALini,filePATH_d3wrapper,fileWIND,dudFILE,stringL,stringU,fileWINDcal,&
PATHweb,pathREGR,fileWEB,PATHfileANALYSIS,threadFILE,threadFILEcopy