tracebackqq() with ifort leads to segmentation fault

511 views Asked by At

Why does the following code lead to segmentation fault when compiled with ifort?

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

Executing ifort testtrb.f90 ; ./a.out, I got

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

The return of ifort --version is ifort (IFORT) 19.1.1.217 20200306. I also tried ifort (IFORT) 2021.1 Beta 20201112, the result being similar. The value of uname -r is 5.9.0-050900-generic, if it is helpful.

However, changing tracebackqq to backtrace and runing gfortran testtrb.f90 ; ./a.out , I get

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

Finish.

This seems correct.

So why does tracebackqq give rise to SIGSEGV?

Any comments or criticism will be appreciated. Thanks.

1

There are 1 answers

1
Ian Bush On BEST ANSWER

The program is not behaving as you expect for two reasons, both documented at https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/a-to-z-reference/t-to-z/tracebackqq.html

  1. Tracebackqq has optional arguments. It thus requires an interface to be in scope at the calling point. This is achieved by using the ifcore module
  2. Bizarrely by default tracebackqq terminates execution. To have the program continue execution you need to provide a non-default user_exit_code

So compiling and running the provided code on the login node of our local cluster I get the same behaviour as above:

[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

Adding use of the module stops the SIGSEGV but the code terminates before printing Finish as documented:

[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

Finally adding the non-default user_exit_code gives the desired behaviour

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