-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Description
Short description
I have Julia code that gets called from C. One of my Julia functions is using a macro to load a variable from a .bson file.
With that macro my executable produces a segmentation fault. Replacing the macro seems to solve my issue, so I suspect that there is either a problem in the Julia macro itself or that embedded Julia has some issue with macros in general.
But of course it could be that I have some bug in my C code as I'm fairly new to calling Julia from C.
I asked a question about this on discourse: https://discourse.julialang.org/t/embedded-julia-segmentation-fault-when-loading-bson-file/74795
How to reproduce
C sources
mwe.c
#include <stdio.h>
#include <stdlib.h>
#include <julia.h>
JULIA_DEFINE_FAST_TLS // only define this once, in an executable (not in a shared library) if you want fast code.
int main(int argc, char *argv[]){
/* required: setup the Julia context */
jl_init();
jl_eval_string("Base.include(Main, \"mwe.jl\")");
jl_eval_string("using Main.MWE");
jl_module_t* MWE = (jl_module_t *)jl_eval_string("Main.MWE");
/* Get loadNN and evalNN function */
jl_function_t *loadVar = jl_get_function(MWE, "loadVar");
jl_function_t *evalFunc = jl_get_function(MWE, "evalFunc");
/* Create thin wrapper around arrays */
jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1);
size_t length_inputs = 2;
double *inputs = (double*)calloc(length_inputs, sizeof(double));
jl_array_t *jl_inputs = jl_ptr_to_array_1d(array_type, inputs, length_inputs, 0);
size_t length_outputs = 2;
double *outputs = (double*)calloc(length_outputs, sizeof(double));
jl_array_t *jl_outputs = jl_ptr_to_array_1d(array_type, outputs, length_outputs, 0);
/* Load data from BSON */
const char filename[]= "savedVar.bson";
jl_value_t *jl_filename = jl_cstr_to_string(filename);
jl_call1(loadVar, (jl_value_t*)jl_filename);
/* Evaluate NN */
inputs[0] = 1.0;
inputs[1] = 2.0;
jl_call2(evalFunc, (jl_value_t*)jl_inputs, (jl_value_t*)jl_outputs);
printf("Return value: [");
for(int i=0; i<length_outputs-1; i++) {
printf("%.1f, ", outputs[i]);
}
printf("%f]\n", outputs[length_outputs-1]);
/* Notify Julia that programm is going to end */
jl_atexit_hook(0);
return 0;
}Julia sources
mwe.jl
module MWE
using BSON: @load, @save
export loadVar
export saveVar
export evalFunc
function saveVar(modelFile::String)
someVar = [1.0, 2.0]
@save abspath(modelFile) someVar
end
function loadVar(modelFile::String)
@info "Loading var from \"$(modelFile)\""
@load abspath(modelFile) someVar # Using the next two lines insted of the macro seems to work.
#dict = BSON.load(modelFile)
#someVar = dict[:someVar]
println(someVar)
end
function evalFunc!(inputs::Array{Float64}, outputs::Array{Float64})
@info "Inputs $(inputs)"
@info "Outputs $(outputs)"
end
endCompile & Run
Create .bson file from Julia:
julia> include("mwe.jl")
julia> MWE.saveVar("savedVar.bson")Compile sources and run:
$ export JULIA_PATH=/opt/julia/julia-1.7.1
$ clang -o mwe -fPIC -g -O0 -I$JULIA_PATH/include/julia -L$JULIA_PATH/lib -Wl,-rpath,$JULIA_PATH/lib mwe.c -ljuliaTry program mew:
$ ./mwe
[ Info: Loading var from "savedVar.bson"
[1.0, 2.0]
signal (11): Segmentation fault
in expression starting at none:0
jl_object_id__cold at /buildworker/worker/package_linux64/build/src/builtins.c:400
type_hash at /buildworker/worker/package_linux64/build/src/jltypes.c:1125
typekey_hash at /buildworker/worker/package_linux64/build/src/jltypes.c:1137 [inlined]
jl_precompute_memoized_dt at /buildworker/worker/package_linux64/build/src/jltypes.c:1197
inst_datatype_inner at /buildworker/worker/package_linux64/build/src/jltypes.c:1510
jl_inst_arg_tuple_type at /buildworker/worker/package_linux64/build/src/jltypes.c:1606
arg_type_tuple at /buildworker/worker/package_linux64/build/src/gf.c:1845 [inlined]
jl_lookup_generic_ at /buildworker/worker/package_linux64/build/src/gf.c:2373 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2425
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
jl_call2 at /buildworker/worker/package_linux64/build/src/jlapi.c:256
main at /home/andreas/publications/openmodelica-workshop-2022/example/callJuliaFromC/mwe.c:38
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at ./mwe (unknown line)
Allocations: 1561933 (Pool: 1561377; Big: 556); GC: 2
Segmentation faultGDB output:
(gdb) r
Starting program: /home/andreas/publications/openmodelica-workshop-2022/example/callJuliaFromC/mwe
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff1f06700 (LWP 28205)]
[New Thread 0x7fffdf645700 (LWP 28206)]
[New Thread 0x7fffd6e44700 (LWP 28207)]
[New Thread 0x7fffce643700 (LWP 28208)]
[New Thread 0x7fffcde42700 (LWP 28209)]
[New Thread 0x7fffbd641700 (LWP 28210)]
[New Thread 0x7fffb4e40700 (LWP 28211)]
[New Thread 0x7fffac63f700 (LWP 28212)]
[ Info: Loading var from "savedVar.bson"
[1.0, 2.0]
Thread 1 "mwe" received signal SIGSEGV, Segmentation fault.
jl_object_id__cold (dt=0x0, v=0x7fffee2e4ae0) at /buildworker/worker/package_linux64/build/src/builtins.c:400
400 /buildworker/worker/package_linux64/build/src/builtins.c: No such file or directory.
(gdb) bt
#0 jl_object_id__cold (dt=0x0, v=0x7fffee2e4ae0) at /buildworker/worker/package_linux64/build/src/builtins.c:400
#1 0x00007ffff71bba60 in type_hash (kj=<optimized out>, failed=failed@entry=0x7fffffffd3bc) at /buildworker/worker/package_linux64/build/src/jltypes.c:1125
#2 0x00007ffff71bec6e in typekey_hash (nofail=<optimized out>, n=<optimized out>, key=<optimized out>, tn=<optimized out>) at /buildworker/worker/package_linux64/build/src/jltypes.c:1137
#3 jl_precompute_memoized_dt (dt=0x7fffedd25ff0, cacheable=<optimized out>, cacheable@entry=0) at /buildworker/worker/package_linux64/build/src/jltypes.c:1197
#4 0x00007ffff71c05e3 in inst_datatype_inner (dt=<optimized out>, p=<optimized out>, iparams=<optimized out>, ntp=ntp@entry=3, stack=0x7fffffffd470, stack@entry=0x0, env=env@entry=0x0)
at /buildworker/worker/package_linux64/build/src/jltypes.c:1510
#5 0x00007ffff71c276f in jl_inst_arg_tuple_type (arg1=arg1@entry=0x7ffff15dc7c8, args=args@entry=0x7fffffffd658, nargs=nargs@entry=3, leaf=leaf@entry=1) at /buildworker/worker/package_linux64/build/src/jltypes.c:1606
#6 0x00007ffff71ce4ca in arg_type_tuple (nargs=3, args=0x7fffffffd658, arg1=0x7ffff15dc7c8) at /buildworker/worker/package_linux64/build/src/gf.c:1845
#7 jl_lookup_generic_ (world=31325, callsite=<optimized out>, nargs=3, args=0x7fffffffd658, F=0x7ffff15dc7c8) at /buildworker/worker/package_linux64/build/src/gf.c:2373
#8 jl_apply_generic (F=0x7ffff15dc7c8, args=0x7fffffffd658, nargs=2) at /buildworker/worker/package_linux64/build/src/gf.c:2425
#9 0x00007ffff7231065 in jl_apply (nargs=3, args=0x7fffffffd650) at /buildworker/worker/package_linux64/build/src/julia.h:1788
#10 jl_call2 (f=0x7ffff15dc7c8, a=0x7fffee2e4ac0, b=0x7fffee2e4af0) at /buildworker/worker/package_linux64/build/src/jlapi.c:256
#11 0x0000000000401394 in main (argc=1, argv=0x7fffffffd988) at mwe.c:38
Version 'n stuff
julia> versioninfo()
Julia Version 1.7.1
Commit ac5cc99908 (2021-12-22 19:35 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i7-10700KF CPU @ 3.80GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
(@v1.7) pkg> status BSON
Status `~/.julia/environments/v1.7/Project.toml`
[fbb218c0] BSON v0.3.4
Metadata
Metadata
Assignees
Labels
No labels