从gfortran应用程序获取SIGSEGV后的符号回溯

时间:2014-03-15 17:39:20

标签: gcc gdb gfortran

我正在使用带有标志-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

2 个答案:

答案 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中的一个错误。

要消除前者,请尝试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。