20.4. Common Issues
In this subsection, we list some common issues users run into when using the Fortran interfaces.
Strange Segmentation Fault in User-Supplied Functions
One common issue we have seen trip up users (and even ourselves) has the symptom of segmentation fault in a user-supplied function (such as the RHS) when trying to use one of the callback arguments. For example, in the following RHS function, we will get a segfault on line 21:
1integer(c_int) function ff(t, yvec, ydotvec, user_data) &
2 result(ierr) bind(C)
3
4 use, intrinsic :: iso_c_binding
5 use fsundials_nvector_mod
6 implicit none
7
8 real(c_double) :: t ! <===== Missing value attribute
9 type(N_Vector) :: yvec
10 type(N_Vector) :: ydotvec
11 type(c_ptr) :: user_data
12
13 real(c_double) :: e
14 real(c_double) :: u, v
15 real(c_double) :: tmp1, tmp2
16 real(c_double), pointer :: yarr(:)
17 real(c_double), pointer :: ydotarr(:)
18
19 ! get N_Vector data arrays
20 yarr => FN_VGetArrayPointer(yvec)
21 ydotarr => FN_VGetArrayPointer(ydotvec) ! <===== SEGFAULTS HERE
22
23 ! extract variables
24 u = yarr(1)
25 v = yarr(2)
26
27 ! fill in the RHS function:
28 ! [0 0]*[(-1+u^2-r(t))/(2*u)] + [ 0 ]
29 ! [e -1] [(-2+v^2-s(t))/(2*v)] [sdot(t)/(2*vtrue(t))]
30 tmp1 = (-ONE+u*u-r(t))/(TWO*u)
31 tmp2 = (-TWO+v*v-s(t))/(TWO*v)
32 ydotarr(1) = ZERO
33 ydotarr(2) = e*tmp1 - tmp2 + sdot(t)/(TWO*vtrue(t))
34
35 ! return success
36 ierr = 0
37 return
38
39end function
The subtle bug in the code causing the segfault is on line 8. It should read
real(c_double), value :: t instead of real(c_double) :: t (notice the
value attribute). Fundamental types that are passed by value in C need
the value attribute.