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.