Я пытаюсь вызвать подпрограмму SPLEV библиотеки FITPACK через две функции ('wer' и 'qwe'), вложенные одна в другую (код ниже).
При выполнении скомпилированной программы появляется следующее сообщение:
QWE
Программа получила сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.
Backtrace для этой ошибки:
0 0x7F3EE4BF3E08
1 0x7F3EE4BF2F90
2 0x7F3EE453A4AF
3 0x4041B6 в splev_
4 0x400BD0 в значении.3386 по pr.f90:?
5 0x400A6B в MAIN__ на pr.f90:?
Ошибка сегментирования (сделан дамп памяти)
Если я скомпилирую свою программу с флагами -g -fbacktrace -fsanitize=address,zero,undefined
, появится следующее сообщение:
QWE
0,37051690837706980
Программа получила сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.
Backtrace для этой ошибки:
0 0x7FAB5F45CE08
1 0x7FAB5F45BF90
2 0x7FAB5EDA34AF
3 0x4075F0 в splev_ на splev.f: 73 (дискриминатор 2)
4 0x400DDE в значении.3386 по pr.f90: 87
5 0x400FFA в кв.3406 по pr.f90: 43
6 0x400F88 в wer.3403 по pr.f90: 48
7 0x400D08 в MAIN__ на pr.f90: 38
Ошибка сегментирования (сделан дамп памяти)
Если я скомпилирую свою программу с флагами -g -fbacktrace -Wall -fcheck=all
, появится следующее сообщение:
QWE
Программа получила сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.
Backtrace для этой ошибки:
0 0x7F2BE6F0FE08
1 0x7F2BE6F0EF90
2 0x7F2BE68564AF
3 0x4075F0 в splev_ на splev.f: 73 (дискриминатор 2)
4 0x400DDE в значении.3386 по pr.f90: 87
5 0x400C46 в MAIN__ на pr.f90: 35
Ошибка сегментирования (сделан дамп памяти)
Если я скомпилирую свою программу с флагами -g -fbacktrace -fsanitize=address
, появится следующее сообщение:
QWE
АСАН: SIGSEGV
=============================================== ==================
== 4796 == ОШИБКА: AddressSanitizer: SEGV по неизвестному адресу 0x000000000000 (шт 0x000000408f67 п.о. 0x7ffe7a134440 sp 0x7ffe7a1341e0 T0)
0 0x408f66 в splev_ /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/splev.f:73
1 0x40145d в значении.3386 (/ home / yurchvlad / Science / Coll_Int / F90 / f90DP / 1 / curfit + 0x40145d)
2 0x4011a3 в intcoll /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/pr.f90:35
3 0x401849 в главном /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/pr.f90:2
4 0x7fcad9b3282f в __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
5 0x400d38 в _start (/ home / yurchvlad / Science / Coll_Int / F90 / f90DP / 1 / curfit + 0x400d38)
AddressSanitizer не может предоставить дополнительную информацию.
РЕЗЮМЕ: AddressSanitizer: SEGV /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/splev.f:73 splev_
== 4796 == ABORTING
Сначала я покажу код, а затем предоставлю некоторую информацию о подпрограммах CURFIT и SPLEV библиотеки FITPACK, которые играют там главную роль.
Вот мой код. Это всего лишь тестовая программа, то есть не путать, что я интерполирую туда массив значений аналитической функции.
PROGRAM IntColl
USE Constants
IMPLICIT NONE
INTEGER :: i, nen ! i = counter
! nen, nmn, ne is sirvice variables, which
! appear on exit of CURFIT and needed on entry
! of SPLEV and SPLINT
REAL(DP) :: foo
REAL(DP) :: MOM1 ! dimensionless neutrino momentum
REAL(DP) :: dmg ( 1 : 2 * NG) ! dimensionless momentum grid
REAL(DP) :: endf( 1 : 2 * NG) ! electron neutrino distribution function
! muon neutrino distribution function
! electron and positron distribution function
REAL(DP) :: ten ( 1 : 2 * NG + k + 1) ! service arrays:
! ten is array arising on exit of working of CURFIT
! and contain knots of the spline (for endf, mndf and edf correspondingly).
REAL(DP) :: cen ( 1 : 2 * NG + k + 1) ! needed on entry of SPLEV and SPLINT
! cen appear on exit of CURFIT, contain coefficients of spline
! (for endf, mndf and edf correspondingly) and needed on entry of SPLEV and SPLINT.
REAL(DP) :: w ( 1 : 2 * NG + k + 1) ! w is array of weights for points on entry of CURFIT.
DO i = 1, 2 * NG
dmg(i) = i / 10.D+00 ! filling arrays to give their
endf(i) = eq_nu_di_fu(dmg(i)) ! on entry into subroutine
w(i) = 1.d+00 ! CURFIT
END DO
MOM1 = .53D+00
PRINT *, 'QWE'
CALL spline(dmg, endf, nen, ten, cen)
foo = value(MOM1, ten, nen, cen)
PRINT *, foo
PRINT *, wer(MOM1)
CONTAINS
REAL(DP) FUNCTION qwe(q) ! qwe and wer is "wrappers" for using
REAL(DP) :: q ! of subroutines spline > curfit
qwe = value(q, ten, nen, cen) ! in main program
END FUNCTION qwe
REAL(DP) FUNCTION wer(q)
REAL(DP) :: q
wer = qwe(q)
END FUNCTION wer
SUBROUTINE spline(x, y, n, t, c) ! spline is "hand-made wrapper" for
IMPLICIT NONE ! more convenient using of subroutine
! CURFIT in main program
INTEGER :: m, nest, n, lwrk, ier
INTEGER, PARAMETER :: iopt = 0
INTEGER :: iwrk( 1 : 10 * NG )
REAL(DP) :: xb, xe, fp
REAL(DP) :: wrk( 1 : 2 * NG * (k + 1) + (2 * NG + k + 1) * (7 + 3 * k) )
REAL(DP) :: x( 1 : 2 * NG), y(1: 2 * NG )
REAL(DP) :: t( 1 : 2 * NG + k + 1 )
REAL(DP) :: c( 1 : 2 * NG + k + 1 )
xb = 0.d+00
xe = x(2 * NG)
m = 2 * NG
nest = m + k + 1
lwrk = 2 * NG * (k + 1) + nest * (7 + 3 * k)
CALL curfit(iopt, m, x, y, w, xb, xe, k, s, nest, n, t, c, fp, wrk, lwrk, iwrk, ier)
END SUBROUTINE spline
REAL(DP) FUNCTION value(q, t, n, c) ! value is "hand-made wrapper" for
IMPLICIT NONE ! more convenient using of subroutine
! SPLEV in main program
INTEGER :: n, ier ! SPLEV should work only after
INTEGER, PARAMETER :: m = 1 ! CURFIT edned its working
REAL(DP) :: q
REAL(DP) :: t( 1 : 2 * NG + k + 1 )
REAL(DP) :: c( 1 : 2 * NG + k + 1 )
REAL(DP) :: ddmg(1), sddmg(1)
ddmg(1) = q
CALL splev(t, n, c, k, ddmg, sddmg, m, ier)
value = sddmg(1)
END FUNCTION value
REAL(DP) FUNCTION eq_nu_di_fu(y) ! eq_nu_di_fy givev values for array
IMPLICIT NONE ! to interpolate
REAL(DP) :: y
eq_nu_di_fu = 1 / (EXP(y) + 1)
END FUNCTION eq_nu_di_fu
END PROGRAM IntColl
Модуль Константы есть:
MODULE CONSTANTS
INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(15, 307)
INTEGER, PARAMETER :: NG = 200 ! NUMBER OF KNOTS OF GRID
INTEGER , PARAMETER :: K = 3 ! THE ORDER OF SPLINE
REAL(DP), PARAMETER :: S = 0.D+00 ! CUBIC SPLINE SMOOTHING FACTOR
END MODULE
Теперь подпрограммы CURFIT и SPLEV, представленные в приведенном выше коде, со всеми их зависимостями находятся в следующих источниках:
https://github.com/jbaayen/fitpackpp/tree/master/fitpack
где эти подпрограммы с двойной точностью
и
http://www.netlib.org/dierckx/
где эти подпрограммы с одинарной точностью.
ЭтоОчень важно отметить, что приведенная выше схема с одинарной точностью работает!
Конечно, если я использую подпрограммы одинарной точности, я изменяю все типы всех переменных соответствующим образом.
Что еще у меня есть?наблюдается:
прямое использование значения FUNCTION работает.
Если закомментирована строка PRINT *, 'QWE' основной программы,значение 'foo' также не печатается.