JuliaArrays / JuliaArrays/StaticArrays.jl
Julia crashes completely when building a SHermitianCompact matrix from a tuple with not enough elements
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 844
- Forks
- 159
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 3
Description
Hello. When I build a SHermitianCompact object and pass as an argument a tuple with less elements than the required ones, Julia crashes completely and shows a fatal error that starts with
[475316] signal 4 (2): Illegal instruction
Later in the issue I've written the whole stacktrace. I've found this because I misread the docstrings of SHermitianCompact. According to the docs, you can build a SHermitianCompact from an AbstractVector containing the lower triangular elements, for example,
julia> SHermitianCompact{2,Int,3}([4,2,3])
2×2 SHermitianCompact{2, Int64, 3} with indices SOneTo(2)×SOneTo(2):
4 2
2 3
If I pass more or less elements than the required ones (3 in this case), a DimensionMismatch exception is raised:
julia> SHermitianCompact{2,Int,3}([4,2,3,5])
ERROR: DimensionMismatch: expected input array of length 3, got length 4
Stacktrace:
[1] dimension_mismatch_fail(::Type{SVector{3, Int64}}, a::Vector{Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:204
[2] convert
@ ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:209 [inlined]
[3] SHermitianCompact{2, Int64, 3}(a::Vector{Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/SHermitianCompact.jl:94
[4] top-level scope
@ REPL[17]:1
julia> SHermitianCompact{2,Int,3}([4,2])
ERROR: DimensionMismatch: expected input array of length 3, got length 2
Stacktrace:
[1] dimension_mismatch_fail(::Type{SVector{3, Int64}}, a::Vector{Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:204
[2] convert
@ ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:209 [inlined]
[3] SHermitianCompact{2, Int64, 3}(a::Vector{Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/SHermitianCompact.jl:94
[4] top-level scope
@ REPL[18]:1
I can also build a SHermitianCompact with a tuple but writing directly the elements. The difference is that now you need the whole array, not just the lower triangular part, for example,
julia> SHermitianCompact{2,Int,3}(4,2,3,7)
2×2 SHermitianCompact{2, Int64, 3} with indices SOneTo(2)×SOneTo(2):
4 2
2 7
Like before, with the vector, passing more or less elements raises an error:
julia> SHermitianCompact{2,Int,3}(4,2,3,7,5)
ERROR: DimensionMismatch: No precise constructor for SHermitianCompact{2, Int64, 3} found. Length of input was 5.
Stacktrace:
[1] _no_precise_size(SA::Type, x::NTuple{5, Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:169
[2] _no_precise_size(SA::Type, x::StaticArrays.Args{NTuple{5, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:168
[3] length_match_size(::Type{SHermitianCompact{2, Int64, 3}}, x::StaticArrays.Args{NTuple{5, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:138
[4] adapt_size(::Type{SHermitianCompact{2, Int64, 3}}, x::StaticArrays.Args{NTuple{5, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:107
[5] construct_type(::Type{SHermitianCompact{2, Int64, 3}}, x::StaticArrays.Args{NTuple{5, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:95
[6] SHermitianCompact{2, Int64, 3}(::Int64, ::Vararg{Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:173
[7] top-level scope
@ REPL[22]:1
julia> SHermitianCompact{2,Int,3}(4,2,3)
ERROR: DimensionMismatch: No precise constructor for SHermitianCompact{2, Int64, 3} found. Length of input was 3.
Stacktrace:
[1] _no_precise_size(SA::Type, x::Tuple{Int64, Int64, Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:169
[2] _no_precise_size(SA::Type, x::StaticArrays.Args{Tuple{Int64, Int64, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:168
[3] length_match_size(::Type{SHermitianCompact{2, Int64, 3}}, x::StaticArrays.Args{Tuple{Int64, Int64, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:138
[4] adapt_size(::Type{SHermitianCompact{2, Int64, 3}}, x::StaticArrays.Args{Tuple{Int64, Int64, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:107
[5] construct_type(::Type{SHermitianCompact{2, Int64, 3}}, x::StaticArrays.Args{Tuple{Int64, Int64, Int64}})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:95
[6] SHermitianCompact{2, Int64, 3}(::Int64, ::Vararg{Int64})
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/convert.jl:173
[7] top-level scope
@ REPL[23]:1
The problem arises if what I pass as an argument is a tuple. Again, a tuple with 4 elements works fine in this case:
julia> SHermitianCompact{2,Int,3}((4,2,3,7))
2×2 SHermitianCompact{2, Int64, 3} with indices SOneTo(2)×SOneTo(2):
4 2
2 7
But passing less elements produces the fatal error:
julia> SHermitianCompact{2,Int,3}((4,2,3))
Unreachable reached at 0x7f8237a41bbf
[475956] signal 4 (2): Illegal instruction
in expression starting at REPL[25]:1
getindex at ./tuple.jl:33 [inlined]
macro expansion at /home/pmc4/.julia/packages/StaticArrays/0cEwi/src/SHermitianCompact.jl:83 [inlined]
SHermitianCompact at /home/pmc4/.julia/packages/StaticArrays/0cEwi/src/SHermitianCompact.jl:73
unknown function (ip: 0x7f8237a41bf2) at (unknown file)
jl_apply at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
do_call at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/interpreter.c:123
eval_value at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/interpreter.c:243
eval_stmt_value at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/interpreter.c:194 [inlined]
eval_body at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/interpreter.c:707
jl_interpret_toplevel_thunk at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/interpreter.c:898
jl_toplevel_eval_flex at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/toplevel.c:1035
__repl_entry_eval_expanded_with_loc at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:301
jl_apply at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
jl_f_invokelatest at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/builtins.c:881
toplevel_eval_with_hooks at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:308
toplevel_eval_with_hooks at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:312
toplevel_eval_with_hooks at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:312
toplevel_eval_with_hooks at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:312
toplevel_eval_with_hooks at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:305 [inlined]
eval_user_input at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:330
repl_backend_loop at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:452
#start_repl_backend#41 at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:427
start_repl_backend at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:424 [inlined]
#run_repl#50 at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:653
run_repl at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/usr/share/julia/stdlib/v1.12/REPL/src/REPL.jl:639
jfptr_run_repl_24210.1 at /home/pmc4/.julia/juliaup/julia-1.12.3+0.x64.linux.gnu/share/julia/compiled/v1.12/REPL/u0gqU_qI7kV.so (unknown line)
run_std_repl at ./client.jl:478
jfptr_run_std_repl_53534.1 at /home/pmc4/.julia/juliaup/julia-1.12.3+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
jl_f_invokelatest at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/builtins.c:881
run_main_repl at ./client.jl:499
repl_main at ./client.jl:586 [inlined]
_start at ./client.jl:561
jfptr__start_39867.1 at /home/pmc4/.julia/juliaup/julia-1.12.3+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
jl_apply at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/julia.h:2391 [inlined]
true_main at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/jlapi.c:971
jl_repl_entrypoint at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/src/jlapi.c:1139
main at /cache/build/tester-amdci4-9/julialang/julia-release-1-dot-12/cli/loader_exe.c:58
__libc_start_call_main at /lib64/libc.so.6 (unknown line)
__libc_start_main at /lib64/libc.so.6 (unknown line)
unknown function (ip: 0x4010b8) at /workspace/srcdir/glibc-2.17/csu/../sysdeps/x86_64/start.S
Allocations: 210147939 (Pool: 210145830; Big: 2109); GC: 81
Illegal instruction (core dumped) julia
I found this because I thought I could also build it from the lower triangular part, like with vectors. Note that if I pass a tuple with more elements, the array is built ignoring every element from index 5 onwards:
julia> SHermitianCompact{2,Int,3}((4,5,2,8,7,78,19,90))
2×2 SHermitianCompact{2, Int64, 3} with indices SOneTo(2)×SOneTo(2):
4 5
5 8
In addition, doing the same with an SVector as the argument produces StackOverflowErrors:
julia> SHermitianCompact{2,Int,3}(SVector(4,5,2,8,7,78,19,90))
Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.
ERROR: StackOverflowError:
Stacktrace:
[1] SHermitianCompact{2, Int64, 3}(a::SVector{8, Int64}) (repeats 79984 times)
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/SHermitianCompact.jl:97
julia> SHermitianCompact{2,Int,3}(SVector(4,5))
Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.
ERROR: StackOverflowError:
Stacktrace:
[1] SHermitianCompact{2, Int64, 3}(a::SVector{2, Int64}) (repeats 79984 times)
@ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/SHermitianCompact.jl:97
Probably there is not a check for the length of the tuple or the SVector passed as an argument unlike when a normal Vector is used.
As an aside, I guess it is because of internal things of the code, but I don't understand why the way of building an SHermitianCompact is different when the input is a vector vs when it is a tuple. Why cannot we pass the lower triangular elements for the later case?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/SHermitianCompact.jl at the constructors around lines 73, 83, and 97, then compare their handling with the conversion paths in src/convert.jl. Reproduce the short-tuple, oversized-tuple, and SVector cases, and add regression coverage showing that invalid lengths raise an exception rather than crash or recurse indefinitely.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100