Unreachable reached at 0x7f5b7ecd6739

I’m probably doing some wrong, on the other hand Julia probably shouldn’t be crashing. To reproduce run this under Atom:

mutable struct Buffer
    data::Vector{UInt8}
    offset::Int
    Buffer(val::Vector{UInt8}) = new(val, 0)
end

function Base.convert(::Type{TYPE}, val::Buffer) where TYPE
    val.offset = 0
    read(val, TYPE)
end

Buffer(Vector{UInt8}())

BTW it also crashes if your run Julia in REPL mode and include() the file. However if you run the file with julia test.jl everything is fine. So it’s something with the attempt to display the Buffer.

On my machine results in:

Unreachable reached at 0x7f5b7ecd6739

signal (4): Illegal instruction
in expression starting at none:0
show at ./multimedia.jl:47
#34 at /home/me/.julia/packages/Atom/X8fAI/src/display/display.jl:17
unknown function (ip: 0x7f5b8c27e739)
sprint at ./strings/io.jl:103
render at /home/me/.julia/packages/Atom/X8fAI/src/display/display.jl:16
Type at /home/me/.julia/packages/Juno/oLB1d/src/types.jl:39
Type at /home/me/.julia/packages/Juno/oLB1d/src/types.jl:40
render at /home/me/.julia/packages/Atom/X8fAI/src/display/display.jl:19
render′ at /home/me/.julia/packages/Atom/X8fAI/src/display/errors.jl:119
displayandrender at /home/me/.julia/packages/Atom/X8fAI/src/display/showdisplay.jl:137
#140 at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:151
jl_f__apply at /usr/bin/../lib/libjulia.so.1 (unknown line)
jl_f__apply_latest at /usr/bin/../lib/libjulia.so.1 (unknown line)
#invokelatest#1 at ./essentials.jl:790 [inlined]
invokelatest at ./essentials.jl:789 [inlined]
#139 at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:150
withpath at /home/me/.julia/packages/CodeTools/xGemk/src/utils.jl:30
withpath at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:47 [inlined]
#138 at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:135 [inlined]
with_logstate at ./logging.jl:395
with_logger at ./logging.jl:491 [inlined]
#137 at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:134 [inlined]
hideprompt at /home/me/.julia/packages/Atom/X8fAI/src/repl.jl:85
macro expansion at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:133 [inlined]
macro expansion at /home/me/.julia/packages/Media/ItEPc/src/dynamic.jl:24 [inlined]
#136 at /home/me/.julia/packages/Atom/X8fAI/src/eval.jl:122
handlemsg at /home/me/.julia/packages/Atom/X8fAI/src/comm.jl:164
unknown function (ip: 0x7f5b7ecb413c)
jl_f__apply at /usr/bin/../lib/libjulia.so.1 (unknown line)
#19 at ./task.jl:268
unknown function (ip: 0x7f5b7ecb0224)
unknown function (ip: 0x7f5b980d1bad)
unknown function (ip: 0xffffffffffffffff)
Allocations: 21830157 (Pool: 21825000; Big: 5157); GC: 49

My environment:

Julia Version 1.2.0
Commit c6da87ff4b (2019-08-20 00:03 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-3820 CPU @ 3.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, sandybridge)
Environment:
  JULIA_EDITOR = atom  -a
  JULIA_NUM_THREADS = 4

The reason for the convert is that my module serializes data to disk as key/value pairs. I have setindex!/getindex implemented as a convenience method to save/load a single data object. Or the caller can use the write/read methods if multiple objects need to saved under one key.

The setindex!/getindex methods just turn around and call the write/read functions for the single object. However the getindex() method doesn’t have the type of the object being read so it just loads the bytes into a Buffer object. When Julia calls the convert() method I finally know the type and just call the read method to decode the bytes into the desired object.

I’m guessing I shouldn’t be using convert() this way…which probably means I need to add a Type parameter to getindex so I can have it decode the bytes directly? Or maybe I should be saving the type for the objects to disk so they can be loaded correctly without depending on the user saving them to the correct type, but I haven’t come across the inverse of string(typeof(val)) yet.

For now it appears if I define Base.show(io::IO, val::Buffer) I don’t get the crash.

The issue you have is that the convert you define is way too general. On more recent version you’ll get an error instead.

julia> Buffer(Vector{UInt8}())
Error showing value of type Buffer:
ERROR: MethodError: convert(::Type{Any}, ::Buffer) is ambiguous. Candidates:
  convert(::Type{Any}, x) in Base at essentials.jl:169
  convert(::Type{TYPE}, val::Buffer) where TYPE in Main at REPL[2]:2
  convert(::Type{T}, x::T) where T>:Union{Missing, Nothing} in Base at missing.jl:68
Possible fix, define
  convert(::Type{Any}, ::Buffer)
3 Likes

Okay, thanks. However I’m not sure how to solve that because currently I can convert it to a: Char, Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, Float16, Float32, Float64, Bool, String, Vector{TYPE}, Vector{Any}, Set{TYPE}, Set{Any}, Dict{K, V}, Dict{Any, V}, Dict{K, Any}, Dict{Any, Any}. And I just added the ability to save/load any random data structure, so I can now convert to a user defined structure…It all depends on what data was saved.

Never mind, I’ve reworked the API to just export read/write I stopped fooling around getindex/setindex.