Skip to content

Commit

Permalink
Fix missing GC root in Symbol construction (#47865)
Browse files Browse the repository at this point in the history
The `Symbol` constructor in boot.jl was not using the unsafe_convert mechanism,
becuase it is unavailable at this point in bootstrap. However, it was also not
GC-rooting the string some other way, resulting in potential memory corruption.
Fix that by manually inlining the :foreigncall and setting up the root
appropriately.

(cherry picked from commit b5a6b0f)
  • Loading branch information
Keno authored and KristofferC committed Dec 14, 2022
1 parent 12a4863 commit 2866e26
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -503,16 +503,19 @@ Array{T}(A::AbstractArray{S,N}) where {T,N,S} = Array{T,N}(A)
AbstractArray{T}(A::AbstractArray{S,N}) where {T,S,N} = AbstractArray{T,N}(A)

# primitive Symbol constructors

## Helper for proper GC rooting without unsafe_convert
eval(Core, quote
_Symbol(ptr::Ptr{UInt8}, sz::Int, root::Any) = $(Expr(:foreigncall, QuoteNode(:jl_symbol_n),
Ref{Symbol}, svec(Ptr{UInt8}, Int), 0, QuoteNode(:ccall), :ptr, :sz, :root))
end)

function Symbol(s::String)
@_foldable_meta
return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int),
ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s),
sizeof(s))
return _Symbol(ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s), sizeof(s), s)
end
function Symbol(a::Array{UInt8,1})
return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int),
ccall(:jl_array_ptr, Ptr{UInt8}, (Any,), a),
Intrinsics.arraylen(a))
return _Symbol(ccall(:jl_array_ptr, Ptr{UInt8}, (Any,), a), Intrinsics.arraylen(a), a)
end
Symbol(s::Symbol) = s

Expand Down

0 comments on commit 2866e26

Please sign in to comment.