From my investigations this is a null-pointer dereference, but not a usercode one.
I also observed other weird compilations that all included a ccall
.
signal (11): Segmentation fault
in expression starting at no file:0
set_ssl_cert_locations at /buildworker/worker/package_linuxppc64le/build/usr/share/julia/stdlib/v0.7/LibGit2/src/error.jl:0
__init__ at /buildworker/worker/package_linuxppc64le/build/usr/share/julia/stdlib/v0.7/LibGit2/src/LibGit2.jl:990
jfptr___init___18949 at /buildworker/worker/package_linuxppc64le/build/usr/lib/julia/sys.so (unknown line)
jl_apply_generic at /buildworker/worker/package_linuxppc64le/build/src/gf.c:2167
jl_apply at /buildworker/worker/package_linuxppc64le/build/src/julia.h:1540 [inlined]
jl_module_run_initializer at /buildworker/worker/package_linuxppc64le/build/src/toplevel.c:90
_julia_init at /buildworker/worker/package_linuxppc64le/build/src/init.c:810
julia_init__threading at /buildworker/worker/package_linuxppc64le/build/src/task.c:302
main at /buildworker/worker/package_linuxppc64le/build/ui/repl.c:234
generic_start_main.isra.0 at /lib64/libc.so.6 (unknown line)
__libc_start_main at /lib64/libc.so.6 (unknown line)
Allocations: 5387 (Pool: 5378; Big: 9); GC: 0
make: *** [julia-base-cache] Segmentation fault (core dumped)
Note that this only occurs when calling this function in the sysimage and not when starting Julia without a sysimage and executing it then.
In that regard it is similar to https://github.com/JuliaLang/julia/pull/26772#issue-180686318 where backtrace
shows different behaviour in the sysimage then normally executed.
Looks like the ccall here is corrupting the stack, causing the callee save area to be overwritten with a null pointer. Taking a look.
>│0x7fffbbf36e00 <git_libgit2_opts+48> std r7,192(r1) │
│0x7fffbbf36e04 <git_libgit2_opts+52> std r8,200(r1) │
│0x7fffbbf36e08 <git_libgit2_opts+56> std r9,208(r1)
Specifically this is where it's being corrupted. Not really sure why it thinks it has so much stack to play with.
Quoth the ABI document:
The Parameter Save Area shall be allocated by the caller for function calls unless a prototype is provided for
the callee indicating that all parameters can be passed in registers. (This requires a Parameter Save Area to
be created for functions where the number and type of parameters exceeds the registers available for parameter
passing in registers, for those functions where the prototype contains an ellipsis to indicate a variadic
function, and functions are declared without prototype.)
git_libgit2_opts
is a varargs function, but we just pass it three integer arguments. I assume our LLVM assumes that it thus need not allocate the parameter save area, but the c prototype requires it to be there. Let me test that theory.
Whoo, excellent sleuthing!
Most helpful comment