Gcc 从gfortran应用程序获取SIGSEGV后带有符号的回溯跟踪
我正在使用gfortran 4.8.1进行编译,其标志为Gcc 从gfortran应用程序获取SIGSEGV后带有符号的回溯跟踪,gcc,gdb,gfortran,Gcc,Gdb,Gfortran,我正在使用gfortran 4.8.1进行编译,其标志为-ggdb-O0-Wall-Wextra-Wtabs-Wsurprising-fbacktrace-fimplicit none-fcheck=all-std=f2008。在gdb中运行时,我得到一个没有过程名称的回溯跟踪: Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () (gdb) bt #0 0x0000000000000
-ggdb-O0-Wall-Wextra-Wtabs-Wsurprising-fbacktrace-fimplicit none-fcheck=all-std=f2008
。在gdb中运行时,我得到一个没有过程名称的回溯跟踪:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x0000000100000000 in ?? ()
#2 0x00007fffffffd760 in ?? ()
#3 0x3f1a36e2eb1c432d in ?? ()
#4 0x3da5fd7fe1796495 in ?? ()
#5 0x4024000000000000 in ?? ()
#6 0x3eb0c6f7a0b5ed8d in ?? ()
#7 0x408f400000000000 in ?? ()
#8 0x408f400000000000 in ?? ()
#9 0x0000000000000000 in ?? ()
在执行segfults的/gyre
之后,我调用gdb./gyre-core
。我看到一个警告无法读取加载映射的路径名:输入/输出错误
,但我不确定这是否与问题有关
我需要做什么才能看到SIGSEGV发生在哪里
更新:
因此,我怀疑堆栈损坏一定与过程点初始化有关,因为在此更改之前,我的代码没有分段错误。我无法提供完整的源代码,但相关的代码片段是
pure function new_default_sim_spec() result(spec)
type(sim_spec_type) :: spec
spec = new_sim_spec(1.0_dp)
end function new_default_sim_spec
pure function new_sim_spec(max_days) result(spec)
type(sim_spec_type) :: spec
real(dp), intent(in) :: max_days
! snipped other attribute assignments
spec%increment_h => increment_h_euler
end function new_sim_spec
abstract interface
pure function increment_h_iface(spec, state_minus_1) result(state)
import :: sim_state_type, sim_spec_type
type(sim_state_type) :: state
class(sim_spec_type), intent(in) :: spec
type(sim_state_type), intent(in) :: state_minus_1
end function increment_h_iface
end interface
type sim_spec_type
! snipped other attribute declarations
procedure(increment_h_iface), pointer :: increment_h => null()
end type sim_spec_type
在gdb中运行时,我得到一个没有过程名称的回溯跟踪:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x0000000100000000 in ?? ()
#2 0x00007fffffffd760 in ?? ()
#3 0x3f1a36e2eb1c432d in ?? ()
#4 0x3da5fd7fe1796495 in ?? ()
#5 0x4024000000000000 in ?? ()
#6 0x3eb0c6f7a0b5ed8d in ?? ()
#7 0x408f400000000000 in ?? ()
#8 0x408f400000000000 in ?? ()
#9 0x0000000000000000 in ?? ()
你是如何经营GDB的
我猜你一定是做了gdb/path/to/core
。请改为尝试gdb/path/to/executable/path/to/core
更新:
gdb./gyre-core
。我看到一个警告
这个警告是不相关的(而且经常是这样,尽管我不了解触发它的确切条件)
检查SIGSEGV
发生在何处的另一个显而易见的方法是从一开始就在GDB下运行二进制文件。您无需等待核心
,一个简单的:
gdb ./gyre
(gdb) run
应该足够了
更新2:
我尝试在gdb下运行程序本身,但遇到了同样的问题。 我看到nm列出了大量预期的函数名,因此二进制文件不能被剥离 这意味着:
中的某种非标准设置,或~/.gdbinit
- GDB中的一个bug
gdb-nx./gyre
对于后者,请尝试不同版本的GDB,或者在某个地方提供二进制文件,我可以看一下
更新3:
GDB无法生成堆栈跟踪的原因是您的堆栈在联机模拟中被损坏。f90:45
:
(gdb) bt
#0 simulation::new_default_sim_spec () at simulation.f90:45
#1 0x0000000000401054 in gyre () at gyre.f90:21
#2 0x0000000000401fad in main (argc=1, argv=0x7fffffffeb24) at gyre.f90:3
#3 0x00007ffff742876d in __libc_start_main (main=0x401f79 <main>, argc=1, ubp_av=0x7fffffffe878, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe868) at libc-start.c:226
#4 0x0000000000400be9 in _start ()
(gdb) n
41 in simulation.f90
(gdb) bt
#0 simulation::new_default_sim_spec () at simulation.f90:41
#1 0x0000000000000000 in ?? ()
(gdb)bt
#0 simulation::simulation.f90:45上的新建\u默认\u sim\u规范()
#1 0x0000000000401054英寸回转体()在回转体处。f90:21
#回转体f90:3处的主管道中有2个0x0000000000401负载(argc=1,argv=0x7fffffffeb24)
#3 0x00007FF742876D位于libc start处的uuu libc_start_main(main=0x401f79,argc=1,ubp_av=0x7fffffffe878,init=,fini=,rtld_fini=,stack_end=0x7fffffe868)中。c:226
#4 0x0000000000400be9英寸的起始值()
(gdb)n
41在simulation.f90中
(gdb)英国电信
#0 simulation::simulation.f90:41上的新建\u默认\u sim\u规范()
#1 0x0000000000000000英寸??()
注意,在第45行之前,堆栈是好的,但是在第45行之后,堆栈不是好的。“擦除”堆栈的特定指令如下:
=> 0x408fde <__simulation_MOD_new_default_sim_spec+93>: movq $0x0,0x8(%rbp)
=>0x408fde:movq$0x0,0x8(%rbp)
由于无法访问您的源代码,并且距离我上次接触Fortran已有20年了,我无法明智地猜测什么样的Fortran代码会引发这样的错误。较新的gcc版本默认使用dwarf-4格式的调试信息。如果您有一个旧的工具链,它可能不理解它。试试-gdwarf-2。对于未剥离的二进制文件,GDB不需要任何调试信息来在堆栈跟踪中显示函数名——符号表就足够了。因此,这个答案不太可能是正确的。这没有帮助,我仍然看到
??
过程名称应该在哪里。可能是二进制文件缺少符号表吗?@hertzsprung您的二进制文件可能缺少符号表,但这与您为构建它提供的命令标志不一致。无需猜测,只需运行nm/path/to/exe
。如果你看到了很多你期望看到的函数,那么你的二进制文件就不会被剥离。我试着在gdb下运行这个程序,但也遇到了同样的问题。我看到很多预期的函数名被nm
列出,因此二进制文件不能被剥离。感谢更新。没有~/.gdbinit
文件存在,而且gdb-nx./gyre
对我来说没有什么区别。我已经在@hertzsprung上传了二进制文件。在我看来,您的“为什么GDB不显示堆栈跟踪”问题已经得到了回答,您有了一个新的“为什么这个Fortran程序会损坏堆栈”问题。最好是作为一个单独的问题来提问,用适当的标记对其进行标记,并提供完整的repo case(这应该相对容易——程序不必崩溃,您只需要通过GDB显示堆栈在某个点上已损坏)。