tracebackqq() с ifort приводит к ошибке сегментации

Почему следующий код приводит к ошибке сегментации при компиляции с 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?

Любые комментарии или критика будут оценены. Спасибо.


person Nuno    schedule 05.12.2020    source источник


Ответы (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

  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.
person Ian Bush    schedule 05.12.2020
comment
Почему вы скомпилировали без опций отладки? Я думаю, что особенно номера строк были бы очень хороши в этом случае. - person albert; 05.12.2020
comment
Потому что не догадался.... Поправлю - person Ian Bush; 05.12.2020