Allocations reported by AllocCheck often have stack traces that only contain stack frames from Julia core/Base (array/dict/set constructors, locks, gc code, etc.) before terminating with multiple call sites. This is unhelpful for debugging and makes it hard to filter out allocations that a developer might consider benign.
Could these cases instead be split into multiple allocations, one for each origin, each with a stack trace going back to the top-level call?
As an example, see the code below, where a simple log statement results in 95 reported allocations, and an attempt to filter out the logging-related ones only removes 30 of them.
julia> using AllocCheck
julia> f() = @warn "Watch out!"
f (generic function with 1 method)
julia> allocs = check_allocs(f, ());
julia> length(allocs)
95
julia> allocs_not_from_loggingJL = filter(allocs) do alloc
for frame in alloc.backtrace
(frame.file == Symbol("./logging.jl")) && return false
end
return true
end;
julia> length(allocs_not_from_loggingJL)
65
julia> allocs_not_from_loggingJL[1] # example of stack trace terminating with "multiple call sites"
Allocation of String in ./strings/string.jl:90
| @eval _string_n(n::Integer) = $(Expr(:foreigncall, QuoteNode(:jl_alloc_string), Ref{String}, Expr(:call, Expr(:core, :svec), :Csize_t), 1, QuoteNode((:ccall,0xe)), :(convert(Csize_t, n))))
Stacktrace:
[1] _string_n
@ ./strings/string.jl:90 [inlined]
[2] StringVector
@ ./iobuffer.jl:32 [inlined]
[3] _similar_data
@ ./iobuffer.jl:142 [inlined]
[4] ensureroom
@ ./iobuffer.jl:337 [inlined]
[5] unsafe_write(to::IOBuffer, p::Ptr{UInt8}, nb::UInt64)
@ Base ./iobuffer.jl:458
[6] multiple call sites
@ unknown:0
Allocations reported by AllocCheck often have stack traces that only contain stack frames from Julia core/Base (array/dict/set constructors, locks, gc code, etc.) before terminating with
multiple call sites
. This is unhelpful for debugging and makes it hard to filter out allocations that a developer might consider benign.Could these cases instead be split into multiple allocations, one for each origin, each with a stack trace going back to the top-level call?
As an example, see the code below, where a simple log statement results in 95 reported allocations, and an attempt to filter out the logging-related ones only removes 30 of them.