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

tracebackqq() with ifort leads to segmentation fault

为什么下面的代码用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的return是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?

如有任何意见或批评,我们将不胜感激。谢谢。

程序未按预期运行有两个原因,均记录在 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

  1. Tracebackqq 有可选参数。因此它需要一个接口来 在调用点的范围内。这是通过使用 ifcore 模块
  2. 奇怪的是,默认情况下 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 但代码在打印 Finish 之前终止,如记录的那样:

[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.