Hi!
I’m developing Julia wrappers to the NASA C library Mtk
used to manipulate remote sensing data files, available from GitHub - nasa/MISR-Toolkit: an API facilitating the access of MISR standard product files. Here is an example:
function jMtkLatLonToPathList(latitude, longitude)
path_cnt = Ref{Cint}(0)
path_list = Ref{Ptr{Cint}}()
status = ccall((:MtkLatLonToPathList, mtklib),
Cint,
(Cdouble, Cdouble, Ref{Cint}, Ref{Ptr{Cint}}),
latitude, longitude, path_cnt, path_list)
if status != 0
error("MTK error $status: ", jMtkErrorMessage(status))
end
julia_path_list = [unsafe_load(path_list[], i) for i in 1:path_cnt[]]
status = @ccall mtklib.MtkStringListFree(path_cnt[]::Ref{Cint}, path_list::Ref{Ptr{Cint}})::Cint
if status != 0
error("jMtkLatLonToPathList status = ", status,
", error message = ", jMtkErrorMessage(status))
end
return path_cnt[], julia_path_list
end
This function works fine on an Intel x86 MacBook Pro (2017) with Julia 1.8.2, and I know the result is correct because it is identical to the output of an IDL implementation on the same platform:
julia> using JMtk15
[ Info: Precompiling JMtk15 [600a0e46-2e83-4a57-a945-993fe116ce31]
julia> latitude = 66.121646
66.121646
julia> longitude = 89.263022
89.263022
julia> path_cnt, path_list = jMtkLatLonToPathList(latitude, longitude)
(17, Int32[7, 8, 9, 10, 11, 12, 13, 14, 146, 147, 148, 149, 150, 151, 152, 153, 154])
I am now porting those wrapper functions to an Apple M2 MacBook Pro (2023). Since the Mtk
library is currently available only for x86 platforms, I am using the x86 version of Julia 1.8.5 under Rosetta 2
. This works fine for dozens of other functions (not involving memory management), but this particular function causes the following issue:
If I comment out the @ccall mtklib.MtkStringListFree
statement and the following if status
block, the output looks correct, but the memory assigned to path_list
may not be properly disposed of (as recommended in the original C source code):
julia> using JMtk15
[ Info: Precompiling JMtk15 [6c71635d-e68b-418f-880a-c8128ca9dc0a]
julia> latitude = 66.121646
66.121646
julia> longitude = 89.263022
89.263022
julia> path_cnt, path_list = jMtkLatLonToPathList(latitude, longitude)
(17, Int32[7, 8, 9, 10, 11, 12, 13, 14, 146, 147, 148, 149, 150, 151, 152, 153, 154])
However, if I re-issue the same command after uncommenting those statements, I run into a malloc error linked to that memory management function:
julia> path_cnt, path_list = jMtkLatLonToPathList(latitude, longitude)
julia(31292,0x2006d02c0) malloc: *** error for object 0x800000007: pointer being freed was not allocated
julia(31292,0x2006d02c0) malloc: *** set a breakpoint in malloc_error_break to debug
signal (6): Abort trap: 6
in expression starting at REPL[4]:1
__pthread_kill at /usr/lib/system/libsystem_kernel.dylib (unknown line)
pthread_kill at /usr/lib/system/libsystem_pthread.dylib (unknown line)
abort at /usr/lib/system/libsystem_c.dylib (unknown line)
malloc_vreport at /usr/lib/system/libsystem_malloc.dylib (unknown line)
malloc_report at /usr/lib/system/libsystem_malloc.dylib (unknown line)
MtkStringListFree at /Applications/Mtk-1.5.0/lib/libMisrToolkit.so.1.5.0 (unknown line)
jMtkLatLonToPathList at /Users/michel/Projects/MISR/MISR_Toolkit.1.5/JMtk15/src/jMtkLatLonToPathList.jl:64
unknown function (ip: 0x10c0292cd)
ijl_apply_generic at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
do_call at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
eval_body at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_interpret_toplevel_thunk at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_toplevel_eval_flex at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
ijl_toplevel_eval_in at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.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-5.0/build/default-macmini-x64-5-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-5.0/build/default-macmini-x64-5-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-5.0/build/default-macmini-x64-5-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-5.0/build/default-macmini-x64-5-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-5.0/build/default-macmini-x64-5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:355
jfptr_run_repl_63566 at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
#967 at ./client.jl:419
jfptr_YY.967_56999 at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_f__call_latest at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.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_57423 at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
true_main at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
jl_repl_entrypoint at /Users/michel/.julia/juliaup/julia-1.8.5+0.x64.apple.darwin14/lib/julia/libjulia-internal.1.8.dylib (unknown line)
Allocations: 4713645 (Pool: 4710179; Big: 3466); GC: 2
MicMac3 ~/Projects/MISR %
Questions:
-
Is there anything wrong with the syntax of the Julia function at the top of this message?
-
Is there anything peculiar to watch for when running Julia under
Rosetta 2
? -
Is it in fact necessary to call the C function
MtkStringListFree
at all, as Julia’s garbage collector may take care of those memory allocations once they are not needed anymore?
Thanks for any comment or suggestion on this matter.