Debugging 为什么gfortran不提供符号回溯?

Debugging 为什么gfortran不提供符号回溯?,debugging,gfortran,backtrace,Debugging,Gfortran,Backtrace,在我使用gfortran编译器使用with–g otion运行fortran代码后,出现以下错误: Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation. Backtrace for this error: #0 0x7F2EE30E57D7 #1 0x7F2EE30E5DDE #2 0x7F2EE2820D3F #3 0x7F2EE2DEC913 #4

在我使用gfortran编译器使用with–g otion运行fortran代码后,出现以下错误:

Program received signal SIGFPE: Floating-point exception - erroneous   arithmetic operation.

Backtrace for this error:
#0  0x7F2EE30E57D7
#1  0x7F2EE30E5DDE
#2  0x7F2EE2820D3F
#3  0x7F2EE2DEC913
#4  0x408A97 in __aerosols_MOD_moment_logn at aerosols.f90:45
#5  0x408A02 in __aerosols_MOD_set_aerosol at aerosols.f90:78 (discriminator 20)
#6  0x6D357B in __test_cases_2d_MOD_standard_2d_cases at test_cases_2d.f90:210
#7  0x67E9FC in __set_profiles_MOD_read_profiles_standard at set_profiles.f90:118
#8  0x463BF8 in __main_MOD_main_loop at main.f90:48
#9  0x401F05 in kid at KiD.f90:17
Floating point exception (core dumped)

我不明白为什么前四个回溯没有告知错误跟踪。我试图用addr2line查找地址,但它也没有提供信息。我怎样才能知道错误跟踪

有几种方法可以让您得到一些没有有用信息的堆栈帧

一种方法是如果你的程序有一个bug并破坏了堆栈。在这种情况下,我建议转到
valgrind
查找问题

另一种方法是,如果所讨论的代码是在没有debuginfo的情况下编译的。有时你仍然可以在这里获得一些信息,但并非总是如此。在这种情况下,解决方案是使用
-g
重新编译代码

第三种方法是,如果您的程序包含一个即时编译器,并且执行在JITted代码中停止。我怀疑这不是你的问题,因为你用的是FORTRAN

判断代码可能来自何处的一种方法是使用
info shared
info proc mappings
,并搜索地址列表,查看有问题帧中的PC值适合它的位置。(是的,手工操作是很不幸的。)如果电脑安装在列出的地图中,那么您就知道在哪里可以解决
-g
问题。如果它不适合任何地方,那么最有可能的堆栈是垃圾

我不明白为什么前四个回溯没有告知错误跟踪

您得到的堆栈跟踪来自某种内部Fortran错误报告机制,而不是您的问题所暗示的GDB。这种机制可能不会处理共享库(请注意,所有“缺失”的帧都离应用程序帧很远——缺失的帧可能在共享库中)


解决方案:在GDB下运行程序,并使用
where
命令。GDB知道如何读取共享库的符号信息,并且可能会提供丢失的信息。

gfortran打印的符号回溯不是由GDB完成的,而是由addr2line完成的。问题是addr2line检查磁盘上的二进制文件,而不是内存中的程序映像。因此,对于以某种随机偏移量加载到内存中的共享库(出于安全原因),addr2line无法将地址转换为符号名,因此gfortran回溯机制会返回到打印地址


您可以通过静态编译来解决这个问题,允许addr2line转换libgfortran(gfortran运行库)中的地址。通常,在任何情况下,前几个堆栈帧都来自libgfortran backtrace打印功能。

假设OP从GDB获得堆栈跟踪。他没有。解决方案可能在GDB下运行。我尝试了
GDB./KiD\u SC\u 2D.exe(GDB),其中
,但结果是
没有堆栈
。安装valgrind-3.10.1后,我还尝试了
valgrind--tool=memcheck KiD_SC_2D.exe
结果是
valgrind:KiD_SC_2D.exe:未找到命令
。我做错了什么?@Beata“(gdb)where”--您需要实际运行应用程序,直到崩溃点,然后才使用
where
。我运行了
gdb KiD_SC_2D.exe
,在崩溃点之后,我只写
where
选项,没有堆栈。我尝试使用
-static libgfortran
选项运行模型,但我得到了两个额外的backrtace错误:
0x6FCF8D in _gfortrani\u backtrace
0x6E87F0 in_gfortrani\u回溯\u处理程序
。模型输出写入netcdf文件。netcdf C和Fortran netcdf库作为共享库安装,
LD_LIBRARY_PATH
export LD_LIBRARY_PATH={NCPATH}/lib:${LD_LIBRARY_PATH}
设置。我不知道这是否是问题的原因?+1可能是正确的解释(addr2line一次只能处理一个二进制文件)-1建议静态链接。我成功地用
gdb
解决了这个问题。我键入了
gdb KiD\u SC\u 2D.exe
,在崩溃点之后,
(gdb)run
命令写入了错误回溯。