我正在使用带有标志-ggdb -O0 -Wall -Wextra -Wtabs -Wsurprising -fbacktrace -fimplicit-none -fcheck=all -std=f2008
的gfortran 4.8.1进行编译。在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 ?? ()
执行./gyre
后哪个段错误,我调用gdb ./gyre core
。我看到警告Can't read pathname for load map: Input/output error
,但我不确定这是否与问题相关。
我需要做些什么来查看SIGSEGV的发生位置?
更新: 所以我怀疑堆栈损坏必须与过程点初始化有关,因为我的代码在此更改之前不是segfaulting。我无法提供完整的源代码,但相关的代码段是
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
答案 0 :(得分:1)
在gdb中运行我得到一个没有过程名称的回溯:
你是如何运行GDB的?
我猜你做了gdb /path/to/core
。请改为gdb /path/to/executable /path/to/core
。
更新
gdb ./gyre core
。我看到了警告......
该警告是无关紧要的(并且经常出现,但我不明白触发它的确切条件)。
检查SIGSEGV
位置的其他显而易见的方法是从一开始就在GDB下运行二进制文件。您无需等待core
,这很简单:
gdb ./gyre
(gdb) run
应该足够了。
更新2:
我尝试在gdb下运行程序本身并遇到同样的问题。 我看到大量的预期函数名称由nm列出,因此二进制文件不能被剥离。
这意味着:
~/.gdbinit
或要消除前者,请尝试gdb -nx ./gyre
。
对于后者,尝试使用不同版本的GDB,或者在某处使二进制文件可用,我可以看看。
更新3:
GDB无法生成堆栈跟踪的原因是您的堆栈在simulation.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 ?? ()
注意第45行之前堆栈是好的,但是不是之后。 “擦除”堆栈的特定指令就是这个:
=> 0x408fde <__simulation_MOD_new_default_sim_spec+93>: movq $0x0,0x8(%rbp)
无法访问您的资源,并且自从我上次触及Fortran以来已有20年,我无法巧妙地猜测哪种Fortran代码会引发这样的错误。
答案 1 :(得分:0)
较新的gcc版本默认为dwarf-4格式的调试信息。如果你有一个较旧的工具链,它可能不理解它。试试-gdwarf-2。