Hi @Gnimuc and colleagues,
I have hit a snag in my attempt to write Julia wrappers for the C functions contained in NASA’s MISR Toolkit available from GitHub - nasa/MISR-Toolkit: an API facilitating the access of MISR standard product files. Specifically, the problematic function is MtkSetRegionByPathBlockRange.c
, whose first few lines read as follows:
#include "MisrSetRegion.h"
#include "MisrCoordQuery.h"
#include "MisrError.h"
#include "MisrUtil.h"
#include "MisrOrbitPath.h"
#include "MisrProjParam.h"
/** \brief Select region by path and block range
*
* \return MTK_SUCCESS if successful.
*
* \par Example:
* In this example, we select the region on path 39 starting at block 50 and ending at block 60.
*
* \code
* MTKt_region region = MTKT_REGION_INIT;
* status = MtkSetRegionByPathBlockRange(39, 50, 60, ®ion);
* \endcode
*/
MTKt_status MtkSetRegionByPathBlockRange(
int path_number, /**< [IN] Path */
int start_block, /**< [IN] Start Block */
int end_block, /**< [IN] End Block */
MTKt_Region *region /**< [OUT] Region */ )
{
...
}
where the following macros are defined in the include files MisrMapQuery.h
and MisrSetRegion.h
:
typedef struct {
double lat; /**< Latitude in decimal degrees */
double lon; /**< Longitude in decimal degrees */
} MTKt_GeoCoord;
#define MTKT_GEOCOORD_INIT { 0.0, 0.0 }
typedef struct {
MTKt_GeoCoord ctr; /**< Center of region */
} MTKt_GeoCenter;
#define MTKT_GEOCENTER_INIT { MTKT_GEOCOORD_INIT }
typedef struct {
double xlat; /**< Som x or latitude extent in meters */
double ylon; /**< Som y or longitude extent in meters */
} MTKt_Extent;
#define MTKT_EXTENT_INIT { 0.0, 0.0 }
typedef struct {
MTKt_GeoCenter geo; /**< Region center coordinate in geographic lat/lon */
MTKt_Extent hextent; /**< Half of the region overall extent in meters (measured from geo.ctr) */
} MTKt_Region;
#define MTKT_REGION_INIT { MTKT_GEOCENTER_INIT, MTKT_EXTENT_INIT }
I have translated those macros in Julia as follows, and included them in the module MISRToolkit called below:
Base.@kwdef mutable struct MTKt_GeoCoord
lat::Cdouble = 0.0
lon::Cdouble = 0.0
end
export MTKt_GeoCoord
mutable struct MTKt_GeoCenter
ctr::MTKt_GeoCoord
end
export MTKt_GeoCenter
Base.@kwdef mutable struct MTKt_Extent
xlat::Cdouble = 0.0
ylon::Cdouble = 0.0
end
export MTKt_Extent
mutable struct MTKt_Region
geo::MTKt_GeoCenter
hextent::MTKt_Extent
end
export MTKt_Region
I have encapsulated that C function in a Julia function as follows, where the location of the shared library mtklib
is also specified in the module MISRToolkit
:
function mtksetregionbypathblockrange!(misr_path, misr_block1, misr_block2, region)
status = ccall((:MtkSetRegionByPathBlockRange, mtklib),
MTKt_status,
(Cint, Cint, Cint, Ptr{MTKt_Region}),
misr_path, misr_block1, misr_block2, region)
return status
end
and then created the test function
function chk_mtksetregionbypathblockrange()
misr_path = convert(Int32, 37)
misr_block1 = convert(Int32, 32)
misr_block2 = convert(Int32, 40)
region = MTKt_Region[]
status = mtksetregionbypathblockrange!(misr_path, misr_block1, misr_block2, region)
# println("typeof(region) = ", typeof(region))
# println("num. elements in region = ", length(region))
# for i in eachindex(region)
# println(i, region(i))
# end
return status
end
I then re-start Julia and call that test function chk_
three times consecutively, first with all three println
statements commented out, then with the first one un-commented, and then the second one also un-commented. This last attempt always results in a segmentation fault which crashes Julia, as does the for loop to print the elements of region:
michel@MicMac2:~$ jMtk
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.8.2 (2022-09-29)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using MISRToolkit
[ Info: Precompiling MISRToolkit [d1318645-6a27-4cd6-895f-df1b29e726af]
julia> status = chk_mtksetregionbypathblockrange()
MTK_SUCCESS::MTKt_status = 0x00000000
julia> using MISRToolkit
julia> status = chk_mtksetregionbypathblockrange()
typeof(region) = Vector{MTKt_Region}
MTK_SUCCESS::MTKt_status = 0x00000000
julia> using MISRToolkit
julia> status = chk_mtksetregionbypathblockrange()
typeof(region) =
signal (11): Segmentation fault: 11
in expression starting at REPL[6]:1
jl_gc_pool_alloc_inner at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_gc_alloc at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
_new_array_ at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
_new_array at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
ijl_alloc_array_1d at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
Array at ./boot.jl:459 [inlined]
Dict at ./dict.jl:90
Set at ./set.jl:9 [inlined]
make_typealias at ./show.jl:531
show_typealias at ./show.jl:721
_show_type at ./show.jl:886
show at ./show.jl:881
unknown function (ip: 0x13d1b4566)
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
print at ./strings/io.jl:35
unknown function (ip: 0x13d1aeea6)
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
print at ./strings/io.jl:46
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
do_apply at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
println at ./strings/io.jl:75
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
println at ./coreio.jl:4
chk_mtksetregionbypathblockrange at /Users/michel/Codes/Julia/MISRToolkit/scripts/chk_mtksetregionbypathblockrange.jl:7
unknown function (ip: 0x13d1b4bb5)
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
do_call at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
eval_body at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_interpret_toplevel_thunk at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_toplevel_eval_flex at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_toplevel_eval_flex at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_toplevel_eval_flex at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
ijl_toplevel_eval_in at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
eval at ./boot.jl:368 [inlined]
eval_user_input at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-6.0/build/default-macmini-x64-6-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:151
repl_backend_loop at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-6.0/build/default-macmini-x64-6-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:247
start_repl_backend at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-6.0/build/default-macmini-x64-6-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:232
#run_repl#47 at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-6.0/build/default-macmini-x64-6-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:369
run_repl at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-x64-6.0/build/default-macmini-x64-6-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:355
jfptr_run_repl_65939.clone_1 at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
#967 at ./client.jl:419
jfptr_YY.967_55066.clone_1 at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_f__call_latest at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
#invokelatest#2 at ./essentials.jl:729 [inlined]
invokelatest at ./essentials.jl:726 [inlined]
run_main_repl at ./client.jl:404
exec_options at ./client.jl:318
_start at ./client.jl:522
jfptr__start_36967.clone_1 at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
true_main at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
jl_repl_entrypoint at /Applications/Julia-1.8.app/Contents/Resources/julia/lib/julia/libjulia-internal.1.dylib (unknown line)
Allocations: 5507277 (Pool: 5499187; Big: 8090); GC: 6
/Users/michel/Codes/Scripts/bash/jMtk: line 4: 1187 Segmentation fault: 11 julia --project=.
michel@MicMac2:~$
I suspect something is improperly setup, though the return code is zero in the first two cases. I was surprised that a probable error on my part could crash Julia with a segmentation fault… But why is it that I cannot inquire about the length of the variable region
, which appears to be a Vector
, and why would trying to print some information on the screen in the chk_
function result in a segmentation fault? Thanks in advance for any suggestion on how to proceed, especially to retrieve the four numerical values of region after the ccall
.