Repository: SETI/rms-cspyce (language: python)

Issue:
dskmi2 results in segmentation fault
dskmi2 is a function that makes a spatial index for a DSK type 2 segment. The index is returned as a pair of arrays, one of type SpiceInt and one of type SpiceDouble.

Here is the current unit test that includes this function:

```
def test_dskw02_dskrb2_dskmi2():
    dskpath = os.path.join(TEST_FILE_DIR, "TESTdskw02.dsk")
    cleanup_kernel(dskpath)
    # open the dsk file
    handle = cs.dasopr(ExtraKernels.phobosDsk)
    # get the dladsc from the file
    dladsc = cs.dlabfs(handle)
    # declare some variables
    finscl = 5.0
    corscl = 4
    center = 401
    surfid = 1
    dclass = 2
    frame = "IAU_PHOBOS"
    first = -50 * cs.jyear()
    last = 50 * cs.jyear()
    # stuff from csdsk.h
    cs_DSK02_MAXVRT = 16000002 // 128  # divide to lower memory usage
    cs_DSK02_MAXPLT = 2 * (cs_DSK02_MAXVRT - 2)
    cs_DSK02_MAXVXP = cs_DSK02_MAXPLT // 2
    cs_DSK02_MAXCEL = 60000000 // 128  # divide to lower memory usage
    cs_DSK02_MXNVLS = cs_DSK02_MAXCEL + (cs_DSK02_MAXVXP // 2)
    cs_DSK02_MAXCGR = 100000 // 128  # divide to lower memory usage
    cs_DSK02_IXIFIX = cs_DSK02_MAXCGR + 7
    cs_DSK02_MAXNPV = 3 * (cs_DSK02_MAXPLT // 2) + 1
    cs_DSK02_SPAISZ = (
        cs_DSK02_IXIFIX
        + cs_DSK02_MAXVXP
        + cs_DSK02_MXNVLS
        + cs_DSK02_MAXVRT
        + cs_DSK02_MAXNPV
    )
    worksz = cs_DSK02_MAXCEL
    voxpsz = cs_DSK02_MAXVXP
    voxlsz = cs_DSK02_MXNVLS
    spaisz = cs_DSK02_SPAISZ
    # get verts, number from dskb02 test
    vrtces = cs.dskv02(handle, dladsc, 1)
    # get plates, number from dskb02 test
    plates = cs.dskp02(handle, dladsc, 1)
    # close the input kernel
    cs.dskcls(handle, optmiz=True)
    cs.kclear()
    # open new dsk file
    handle = cs.dskopn(dskpath, "TESTdskw02.dsk/AA/29-SEP-2017", 0)
    # create spatial index
    spaixd, spaixi = cs.dskmi2(vrtces, plates, finscl, corscl, False)
    # do stuff
    corsys = 1
    mncor1 = -cs.pi()
    mxcor1 = cs.pi()
    mncor2 = -cs.pi() / 2
    mxcor2 = cs.pi() / 2
    # Compute plate model radius bounds.
    corpar = np.zeros(10)
    mncor3, mxcor3 = cs.dskrb2(vrtces, plates, corsys, corpar)
    # Write the segment to the file
    cs.dskw02(
        handle,
        center,
        surfid,
        dclass,
        frame,
        corsys,
        corpar,
        mncor1,
        mxcor1,
        mncor2,
        mxcor2,
        mncor3,
        mxcor3,
        first,
        last,
        vrtces,
        plates,
        spaixd,
        spaixi,
    )
    # Close the dsk file
    cs.dskcls(handle, optmiz=True)
    # cleanup
    cs.kclear()
    cleanup_kernel(dskpath)
```

When the test reaches the `dskmi2` function, a segmentation fault occurs and everything breaks. I have tried this on VSCode and Spyder, and it is currently being run with the most recent version of `cspyce`.


Discussion / hints:
At first I was unsure what the arguments were supposed to be.  But now I can look at SpiceyPy, and get a better idea.
Okay.  I need help from Mark or Matt.

I'm calling the CSPICE function `dskmi2` with the following arguments, and it SEGVs. 

```
nv       422 
vrtces 0x157474e00   double[422, 3]
np.    840 
plates 0x157477600    int[840, 3]
finscl 5.000000 
corscl 4 
worksz 234375 
voxpsz 62498 2
voxlsz 65624 
makvtl 0 
spxisz 578514 
work.  0x148300000    int[234375, 2]
spaixd 0x280000000   double[148100010]
spaixi 0x1484d0000.    double[578514]
```
There seems to be some disagreement as to whether the size of `spaixd `is supposed to be 148m or 10.  We use `SPICE_DSK02_SPAISZ`, while spiceypy uses `SPICE_DSK02_SPADSZ`.    In either case, we get a SEGV.

As far as I can tell, this all looks reasonable.  If we are calling this with the wrong arguments, This is beyond me.  Help.

(Just to be clear.  I have made changes to the code.  This is not what `dskmi2` would be called with in the current implementation.  But I can't fix the problem if I don't understand what's supposed to be happening.)
Hi @fyellin.  Thank you very much for working on this, and thank you for identifying the problems with this function.  I think you should move on to the next function for now.  We will circle back and address this when we can. 
@matthewtiscareno .  I have moved on.  Do you have any idea if spaixd is supposed to have length 10 or 148,000,000?  Two very different constants that differ by one letter.
According to the IDL implementation, it should be length 10.
I've added some debugging that let's me callback from CSpice to Python.  I can now examine more carefully the arguments that are passed.  I don't know if these arguments are reasonable or not. 

| Header | Header | Header |
|--------|--------|--------|
|        SpiceInt      |               nv             |                 100
|        ConstSpiceDouble |   vrtces[][3] |     100x3 array of doubles
|        SpiceInt      |               np         |                     100
|        ConstSpiceInt      |     plates[][3]      |     100x3 array of ints
|        SpiceDouble     |        finscl      |              5.0
|        SpiceInt          |          corscl        |                4
|        SpiceInt        |            worksz      |                234375
|        SpiceInt        |           voxpsz       |                62498
|        SpiceInt           |        voxlsz         |              265624
|        SpiceBoolean  |       makvtl        |        0
|        SpiceInt      |             spxisz          |             578514
|        SpiceInt       |           work[][2]       |          234375 x 2 array of 0
|        SpiceDouble     |     spaixd[SPICE_DSK02_SPADSZ]  | array of 10 double zeros
|        SpiceInt          |       spaixi[]              |        array of 5758514  integer zeros

The 100x3 array of doubles is:
```
[[ 5.12656958e-16 -0.00000000e+00 -8.37260000e+00]
 [ 1.42278634e+00 -0.00000000e+00 -8.06902232e+00]
 [ 1.04153527e+00 -1.04153527e+00 -8.35353328e+00]
 [ 9.40266798e-17 -1.53562293e+00 -8.70895040e+00]
 [-1.08104838e+00 -1.08104838e+00 -8.67044442e+00]
 [-1.50585963e+00 -1.84408527e-16 -8.54015435e+00]
 [-1.02627274e+00  1.02627274e+00 -8.23112168e+00]
 [-2.66112101e-16  1.44869465e+00 -8.21595564e+00]
 [ 1.00784229e+00  1.00784229e+00 -8.08330204e+00]
 [ 2.91325918e+00 -0.00000000e+00 -8.00411381e+00]
 [ 2.49446219e+00 -1.44017842e+00 -7.91371538e+00]
 [ 1.50976242e+00 -2.61498521e+00 -8.29607630e+00]
 [ 1.90723001e-16 -3.11484585e+00 -8.55796864e+00]
 [-1.54938545e+00 -2.68361432e+00 -8.51380308e+00]
 [-2.82297554e+00 -1.62984569e+00 -8.95592846e+00]
 [-3.24734445e+00 -3.97671865e-16 -8.92200556e+00]
 [-2.78953477e+00  1.61053865e+00 -8.84983716e+00]
 [-1.58840995e+00  2.75120674e+00 -8.72824094e+00]
 [-5.65264425e-16  3.07725784e+00 -8.45469642e+00]
 [ 1.45414994e+00  2.51866158e+00 -7.99048826e+00]
 [ 2.49612090e+00  1.44113608e+00 -7.91897765e+00]
 [ 4.49675000e+00 -0.00000000e+00 -7.78859947e+00]
 [ 4.28094314e+00 -1.39096275e+00 -7.79639370e+00]
 [ 3.65210497e+00 -2.65340958e+00 -7.81891036e+00]
 [ 2.67430534e+00 -3.68086552e+00 -7.88048476e+00]
 [ 1.41974768e+00 -4.36953406e+00 -7.95773423e+00]
 [ 2.86227243e-16 -4.67460000e+00 -8.09664471e+00]
 [-1.47068913e+00 -4.52631573e+00 -8.24326281e+00]
 [-2.85707717e+00 -3.93242936e+00 -8.41906596e+00]
 [-4.07149938e+00 -2.95811745e+00 -8.71680550e+00]
 [-4.92347693e+00 -1.59973463e+00 -8.96656722e+00]
 [-5.39315000e+00 -6.60448576e-16 -9.34120981e+00]
 [-5.21064844e+00  1.69304231e+00 -9.48955996e+00]
 [-4.36909628e+00  3.17433426e+00 -9.35394039e+00]
 [-3.13101448e+00  4.30947173e+00 -9.22628824e+00]
 [-1.52947961e+00  4.70725423e+00 -8.57278547e+00]
 [-8.41295381e-16  4.57995000e+00 -7.93270610e+00]
 [ 1.37269984e+00  4.22473570e+00 -7.69402949e+00]
 [ 2.56368416e+00  3.52860852e+00 -7.55451280e+00]
 [ 3.55522518e+00  2.58302229e+00 -7.61149727e+00]
 [ 4.31589447e+00  1.40231912e+00 -7.86004656e+00]
 [ 6.68017023e+00 -0.00000000e+00 -7.96111688e+00]
 [ 6.24144800e+00 -1.67239095e+00 -7.70066176e+00]
 [ 5.42068935e+00 -3.12963645e+00 -7.45951097e+00]
 [ 4.32175300e+00 -4.32175300e+00 -7.28385698e+00]
 [ 2.96013336e+00 -5.12710138e+00 -7.05549913e+00]
 [ 1.53487308e+00 -5.72822433e+00 -7.06744943e+00]
 [ 3.69903069e-16 -6.04117507e+00 -7.19959209e+00]
 [-1.68094215e+00 -6.27336150e+00 -7.74003645e+00]
 [-3.35843670e+00 -5.81698300e+00 -8.00485801e+00]
 [-5.07593717e+00 -5.07593717e+00 -8.55495453e+00]
 [-6.24495121e+00 -3.60552426e+00 -8.59379298e+00]
 [-7.02897873e+00 -1.88340917e+00 -8.67231254e+00]
 [-7.33292105e+00 -8.97994171e-16 -8.73903501e+00]
 [-7.30974299e+00  1.95863973e+00 -9.01871783e+00]
 [-6.25803296e+00  3.61307701e+00 -8.61179503e+00]
 [-4.91894614e+00  4.91894614e+00 -8.29036278e+00]
 [-3.37187096e+00  5.84025183e+00 -8.03687867e+00]
 [-1.66345711e+00  6.20810647e+00 -7.65952518e+00]
 [-1.15637216e-15  6.29520473e+00 -7.50233286e+00]
 [ 1.50404552e+00  5.61317431e+00 -6.92550139e+00]
 [ 2.92529427e+00  5.06675831e+00 -6.97245992e+00]
 [ 4.32693452e+00  4.32693452e+00 -7.29258989e+00]
 [ 5.57761473e+00  3.22023737e+00 -7.67545890e+00]
 [ 6.49352737e+00  1.73993542e+00 -8.01167581e+00]
 [ 9.20272171e+00 -0.00000000e+00 -7.72200039e+00]
 [ 8.81224159e+00 -2.01133664e+00 -7.58450812e+00]
 [ 7.80858331e+00 -3.76041553e+00 -7.27237046e+00]
 [ 6.68206447e+00 -5.32876860e+00 -7.17151708e+00]
 [ 4.99185482e+00 -6.25958795e+00 -6.71809470e+00]
 [ 3.28325909e+00 -6.81775776e+00 -6.34958457e+00]
 [ 1.63381683e+00 -7.15821923e+00 -6.16092640e+00]
 [ 4.50931989e-16 -7.36452146e+00 -6.17956724e+00]
 [-1.68060835e+00 -7.36322629e+00 -6.33737160e+00]
 [-3.67792025e+00 -7.63728009e+00 -7.11283057e+00]
 [-5.55826544e+00 -6.96984441e+00 -7.48037653e+00]
 [-7.20156565e+00 -5.74305696e+00 -7.72907106e+00]
 [-8.16230169e+00 -3.93075732e+00 -7.60179911e+00]
 [-8.76175533e+00 -1.99981348e+00 -7.54105568e+00]
 [-8.84758350e+00 -1.08348070e-15 -7.42400406e+00]
 [-8.97930928e+00  2.04946875e+00 -7.72829971e+00]
 [-8.04745537e+00  3.87545025e+00 -7.49483925e+00]
 [-6.84245462e+00  5.45667547e+00 -7.34365560e+00]
 [-5.32489987e+00  6.67721324e+00 -7.16631050e+00]
 [-3.55028855e+00  7.37225013e+00 -6.86600013e+00]
 [-1.83838698e+00  8.05449964e+00 -6.93233581e+00]
 [-1.48822050e-15  8.10176263e+00 -6.79818604e+00]
 [ 1.76217390e+00  7.72058833e+00 -6.64494547e+00]
 [ 3.33667163e+00  6.92867003e+00 -6.45288053e+00]
 [ 4.88281396e+00  6.12285505e+00 -6.57134629e+00]
 [ 6.36775248e+00  5.07811315e+00 -6.83418214e+00]
 [ 7.56846893e+00  3.64478254e+00 -7.04874465e+00]
 [ 8.73793120e+00  1.99437578e+00 -7.52055075e+00]
 [ 1.10647736e+01 -0.00000000e+00 -6.38825000e+00]
 [ 1.09059331e+01 -2.16932498e+00 -6.41990000e+00]
 [ 1.02015551e+01 -4.22562249e+00 -6.37515000e+00]
 [ 9.12477528e+00 -6.09697992e+00 -6.33600000e+00]
 [ 7.11686997e+00 -7.11686997e+00 -5.81090000e+00]
 [ 5.14447115e+00 -7.69924516e+00 -5.34615000e+00]
 [ 3.32225537e+00 -8.02063398e+00 -5.01225000e+00]]
```
The 100x3 array of integers is:
```
[[ 1.  9.  2.]
 [ 1.  2.  3.]
 [ 1.  3.  4.]
 [ 1.  4.  5.]
 [ 1.  5.  6.]
 [ 1.  6.  7.]
 [ 1.  7.  8.]
 [ 1.  8.  9.]
 [ 2.  9. 21.]
 [ 2. 21. 10.]
 [ 2. 10. 11.]
 [ 2. 11.  3.]
 [ 3. 11. 12.]
 [ 3. 12.  4.]
 [ 4. 12. 13.]
 [ 4. 13. 14.]
 [ 4. 14.  5.]
 [ 5. 14. 15.]
 [ 5. 15.  6.]
 [ 6. 15. 16.]
 [ 6. 16. 17.]
 [ 6. 17.  7.]
 [ 7. 17. 18.]
 [ 7. 18.  8.]
 [ 8. 18. 19.]
 [ 8. 19. 20.]
 [ 8. 20.  9.]
 [ 9. 20. 21.]
 [10. 21. 41.]
 [10. 41. 22.]
 [10. 22. 23.]
 [10. 23. 11.]
 [11. 23. 24.]
 [11. 24. 25.]
 [11. 25. 12.]
 [12. 25. 26.]
 [12. 26. 13.]
 [13. 26. 27.]
 [13. 27. 28.]
 [13. 28. 14.]
 [14. 28. 29.]
 [14. 29. 30.]
 [14. 30. 15.]
 [15. 30. 31.]
 [15. 31. 16.]
 [16. 31. 32.]
 [16. 32. 33.]
 [16. 33. 17.]
 [17. 33. 34.]
 [17. 34. 35.]
 [17. 35. 18.]
 [18. 35. 36.]
 [18. 36. 19.]
 [19. 36. 37.]
 [19. 37. 38.]
 [19. 38. 20.]
 [20. 38. 39.]
 [20. 39. 40.]
 [20. 40. 21.]
 [21. 40. 41.]
 [22. 41. 65.]
 [22. 65. 42.]
 [22. 42. 43.]
 [22. 43. 23.]
 [23. 43. 44.]
 [23. 44. 24.]
 [24. 44. 45.]
 [24. 45. 25.]
 [25. 45. 46.]
 [25. 46. 26.]
 [26. 46. 47.]
 [26. 47. 27.]
 [27. 47. 48.]
 [27. 48. 49.]
 [27. 49. 28.]
 [28. 49. 50.]
 [28. 50. 29.]
 [29. 50. 51.]
 [29. 51. 30.]
 [30. 51. 52.]
 [30. 52. 31.]
 [31. 52. 53.]
 [31. 53. 32.]
 [32. 53. 54.]
 [32. 54. 55.]
 [32. 55. 33.]
 [33. 55. 56.]
 [33. 56. 34.]
 [34. 56. 57.]
 [34. 57. 35.]
 [35. 57. 58.]
 [35. 58. 36.]
 [36. 58. 59.]
 [36. 59. 37.]
 [37. 59. 60.]
 [37. 60. 61.]
 [37. 61. 38.]
 [38. 61. 62.]
 [38. 62. 39.]
 [39. 62. 63.]]
```


Fix patch:
diff --git a/swig/cspyce0_part2.i b/swig/cspyce0_part2.i
index 3c1c8361..4e8c948c 100644
--- a/swig/cspyce0_part2.i
+++ b/swig/cspyce0_part2.i
@@ -3396,11 +3396,10 @@ extern void dski02_c(
 %apply (void RETURN_VOID) {void my_dskmi2_c};
 %apply (SpiceInt DIM1, ConstSpiceDouble IN_ARRAY2[][ANY])
                     {(SpiceInt nv, ConstSpiceDouble vrtces[][3])};
-%apply (SpiceInt DIM1, ConstSpiceDouble IN_ARRAY2[][ANY])
+%apply (SpiceInt DIM1, ConstSpiceInt IN_ARRAY2[][ANY])
                     {(SpiceInt np, ConstSpiceInt plates[][3])};
-%apply (SpiceDouble OUT_ARRAY1[ANY])
-                    {SpiceDouble spaixd[SPICE_DSK02_SPADSZ]};
-%apply (SpiceInt OUT_ARRAY1[ANY]) {SpiceInt spaixi[SPICE_DSK02_SPAISZ]};
+%apply (SpiceDouble **OUT_ARRAY1, SpiceInt *SIZE1) {(SpiceDouble **spaixd, SpiceInt *n1)};
+%apply (SpiceInt    **OUT_ARRAY1, SpiceInt *SIZE1) {(SpiceInt **spaixi,    SpiceInt *n2)};
 
 %inline %{
     void my_dskmi2_c(
@@ -3408,18 +3407,25 @@ extern void dski02_c(
         SpiceInt         np, ConstSpiceInt    plates[][3],
         SpiceDouble      finscl,
         SpiceInt         corscl,
+        SpiceInt         worksz,
+        SpiceInt         voxpsz,
+        SpiceInt         voxlsz,
         SpiceBoolean     makvtl,
-        SpiceDouble      spaixd[SPICE_DSK02_SPADSZ],
-        SpiceInt         spaixi[SPICE_DSK02_SPAISZ])
+        SpiceInt         spxisz,
+        SpiceDouble**    spaixd, SpiceInt *n1,
+        SpiceInt**       spaixi, SpiceInt *n2)
     {
-        SpiceInt voxpsz = SPICE_DSK02_MAXVXP;
-        SpiceInt voxlsz = SPICE_DSK02_MXNVLS;
-        SpiceInt worksz = SPICE_DSK02_MAXCEL;
-        SpiceInt spxisz = SPICE_DSK02_SPAISZ;
-        SpiceInt work[SPICE_DSK02_MAXCEL][2];
-
-        dskmi2_c(nv, vrtces, np, plates, finscl, corscl, worksz, voxpsz, voxlsz,
-                 makvtl, spxisz, work, spaixd, spaixi);
+        SpiceInt *work   = my_int_malloc(2 * worksz, "dskmi2");
+        *spaixd = my_malloc(SPICE_DSK02_SPADSZ, "dskmi2");
+        *n1 = SPICE_DSK02_SPADSZ;
+        *spaixi = my_int_malloc(spxisz, "dskmi2");
+        *n2 = spxisz;
+
+        if (work && *spaixi) {
+            dskmi2_c(nv, vrtces, np, plates, finscl, corscl, worksz, voxpsz, voxlsz,
+                     makvtl, spxisz, work, *spaixd, *spaixi);
+        }
+        PyMem_Free(work);
     }
 %}
 


Test patch:
diff --git a/unittests/test_d.py b/unittests/test_d.py
index e484e91e..ca9c9af3 100644
--- a/unittests/test_d.py
+++ b/unittests/test_d.py
@@ -898,7 +898,7 @@ def test_dski02():
     cs.dascls(handle)
 
 
-def fail_dskw02_dskrb2_dskmi2():
+def test_dskw02_dskrb2_dskmi2():
     dskpath = os.path.join(TEST_FILE_DIR, "TESTdskw02.dsk")
     cleanup_kernel(dskpath)
     # open the dsk file
@@ -933,7 +933,7 @@ def fail_dskw02_dskrb2_dskmi2():
     worksz = cs_DSK02_MAXCEL
     voxpsz = cs_DSK02_MAXVXP
     voxlsz = cs_DSK02_MXNVLS
-    spaisz = cs_DSK02_SPAISZ
+    spxisz = cs_DSK02_SPAISZ
     # get verts, number from dskb02 test
     vrtces = cs.dskv02(handle, dladsc, 1)
     # get plates, number from dskb02 test
@@ -945,7 +945,8 @@ def fail_dskw02_dskrb2_dskmi2():
     handle = cs.dskopn(dskpath, "TESTdskw02.dsk/AA/29-SEP-2017", 0)
     # create spatial index
     spaixd, spaixi = cs.dskmi2(
-        vrtces, plates, finscl, corscl, False)
+        vrtces, plates, finscl, corscl, worksz, voxpsz, voxlsz, False, spxisz)
+
     # do stuff
     corsys = 1
     mncor1 = -cs.pi()