Gcc 从gfortran应用程序获取SIGSEGV后带有符号的回溯跟踪

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

我正在使用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  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显示堆栈在某个点上已损坏)。