带有 ifort 的 tracebackqq() 导致分段错误

Posted

技术标签:

【中文标题】带有 ifort 的 tracebackqq() 导致分段错误【英文标题】:tracebackqq() with ifort leads to segmentation fault 【发布时间】:2020-12-05 12:38:14 【问题描述】:

为什么下面的代码用ifort编译会导致段错误?

! testtrb.f90
program testtrb
    call tracebackqq()  ! This is for ifort
    !call backtrace()  ! This is for gfortran 
    print '(/1A/)', 'Finish.'
end program testtrb

执行 ifort testtrb.f90 ; ./a.out, 我得到了

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              0000000000409FFA  Unknown               Unknown  Unknown
libpthread-2.31.s  00007F6E2C9903C0  Unknown               Unknown  Unknown
a.out              000000000040746D  Unknown               Unknown  Unknown
a.out              000000000040383B  Unknown               Unknown  Unknown
a.out              00000000004037E2  Unknown               Unknown  Unknown
libc-2.31.so       00007F6E2C7B00B3  __libc_start_main     Unknown  Unknown
a.out              00000000004036EE  Unknown               Unknown  Unknown

ifort --version 的返回是ifort (IFORT) 19.1.1.217 20200306。我也试过 ifort (IFORT) 2021.1 Beta 20201112,结果相似。 uname -r 的值是5.9.0-050900-generic,如果有帮助的话。

但是,将tracebackqq 更改为backtrace 并运行gfortran testtrb.f90 ; ./a.out ,我明白了

#0  0x7f789588ad3a
#1  0x557b8f35119d
#2  0x557b8f351254
#3  0x7f789569f0b2
#4  0x557b8f3510cd
#5  0xffffffffffffffff

Finish.

这似乎是正确的。

那么为什么tracebackqq 会产生 SIGSEGV?

任何 cmets 或批评将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

由于两个原因,程序未按预期运行,均记录在 https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top/language-reference/a-to-z-reference/t-to-z/tracebackqq.html

    Tracebackqq 具有可选参数。因此,它需要一个接口来 在调用点的范围内。这是通过使用 ifcore模块 奇怪的是,默认情况下tracebackqq 会终止执行。要让程序继续执行,您需要提供非默认 user_exit_code

所以在我们本地集群的登录节点上编译并运行提供的代码,我得到了与上面相同的行为:

[ijb@login12(arcus-b) stack]$ cat tb.f90
! testtrb.f90
program testtrb
    call tracebackqq()  ! This is for ifort
    !call backtrace()  ! This is for gfortran 
    print '(/1A/)', 'Finish.'
end program testtrb
[ijb@login12(arcus-b) stack]$ ifort --version
ifort (IFORT) 19.0.1.144 20181018
Copyright (C) 1985-2018 Intel Corporation.  All rights reserved.

[ijb@login12(arcus-b) stack]$ ifort -g -traceback tb.f90
[ijb@login12(arcus-b) stack]$ ./a.out
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              0000000000409A03  Unknown               Unknown  Unknown
libpthread-2.12.s  000000381E40F710  Unknown               Unknown  Unknown
a.out              00000000004800CF  Unknown               Unknown  Unknown
a.out              0000000000406BE6  Unknown               Unknown  Unknown
a.out              00000000004036A3  MAIN__                      3  tb.f90
a.out              0000000000403662  Unknown               Unknown  Unknown
libc-2.12.so       000000381E01ED5D  __libc_start_main     Unknown  Unknown
a.out              0000000000403569  Unknown               Unknown  Unknown

添加对模块的使用会停止 SIGSEGV,但代码会在打印完成之前终止,如文档所示:

[ijb@login12(arcus-b) stack]$ cat tb2.f90
! testtrb.f90
program testtrb
  Use ifcore, Only : tracebackqq
  Implicit None
  call tracebackqq()  ! This is for ifort
  !call backtrace()  ! This is for gfortran 
  print '(/1A/)', 'Finish.'
end program testtrb
[ijb@login12(arcus-b) stack]$ ifort -g -traceback tb2.f90
[ijb@login12(arcus-b) stack]$ ./a.out
Image              PC                Routine            Line        Source             
a.out              0000000000406EFA  Unknown               Unknown  Unknown
a.out              00000000004036CE  MAIN__                      5  tb2.f90
a.out              0000000000403662  Unknown               Unknown  Unknown
libc-2.12.so       000000381E01ED5D  __libc_start_main     Unknown  Unknown
a.out              0000000000403569  Unknown               Unknown  Unknown

最后添加非默认 user_exit_code 会得到所需的行为

[ijb@login12(arcus-b) stack]$ cat tb3.f90
! testtrb.f90
program testtrb
  Use ifcore, Only : tracebackqq
  Implicit None
  call tracebackqq( user_exit_code = -1 )  ! This is for ifort
  !call backtrace()  ! This is for gfortran 
  print '(/1A/)', 'Finish.'
end program testtrb
[ijb@login12(arcus-b) stack]$ ifort -g -traceback tb3.f90
[ijb@login12(arcus-b) stack]$ ./a.out
Image              PC                Routine            Line        Source             
a.out              0000000000406EFA  Unknown               Unknown  Unknown
a.out              00000000004036CE  MAIN__                      5  tb3.f90
a.out              0000000000403662  Unknown               Unknown  Unknown
libc-2.12.so       000000381E01ED5D  __libc_start_main     Unknown  Unknown
a.out              0000000000403569  Unknown               Unknown  Unknown

Finish.

【讨论】:

为什么编译时没有调试选项?我认为在这种情况下,尤其是行号会非常好。

以上是关于带有 ifort 的 tracebackqq() 导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章

ifort 的 C 的实际大小标志等价物

ifort 中的标志 -r8 会影响声明为 real*4 的变量吗?

使用 ifort 的指数的 Fortran 运算符优先级错误

Centos6.7下安装Intel 的icc / ifort 编译器(非商业版)

ubuntu下用ifort编译fortran为啥汉字无法正常显示,汉字显示的是带问号的小方块

主程序中应该允许返回语句吗?