带有 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 中的标志 -r8 会影响声明为 real*4 的变量吗?
使用 ifort 的指数的 Fortran 运算符优先级错误
Centos6.7下安装Intel 的icc / ifort 编译器(非商业版)