Skip to content

Commit

Permalink
hide internally created methods in stacktraces that occur as a result…
Browse files Browse the repository at this point in the history
… of argument forwarding (#49102)
  • Loading branch information
KristofferC authored Mar 23, 2023
1 parent 489d076 commit 703b3f8
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 1 deletion.
71 changes: 70 additions & 1 deletion base/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,73 @@ function _simplify_include_frames(trace)
return trace[kept_frames]
end

# Collapse frames that have the same location (in some cases)
function _collapse_repeated_frames(trace)
kept_frames = trues(length(trace))
last_frame = nothing
for i in 1:length(trace)
frame::StackFrame, _ = trace[i]
if last_frame !== nothing && frame.file == last_frame.file && frame.line == last_frame.line
#=
Handles this case:
f(g, a; kw...) = error();
@inline f(a; kw...) = f(identity, a; kw...);
f(1)
which otherwise ends up as:
[4] #f#4 <-- useless
@ ./REPL[2]:1 [inlined]
[5] f(a::Int64)
@ Main ./REPL[2]:1
=#
if startswith(sprint(show, last_frame), "#")
kept_frames[i-1] = false
end

#= Handles this case
g(x, y=1, z=2) = error();
g(1)
which otherwise ends up as:
[2] g(x::Int64, y::Int64, z::Int64)
@ Main ./REPL[1]:1
[3] g(x::Int64) <-- useless
@ Main ./REPL[1]:1
=#
if frame.linfo isa MethodInstance && last_frame.linfo isa MethodInstance &&
frame.linfo.def isa Method && last_frame.linfo.def isa Method
m, last_m = frame.linfo.def::Method, last_frame.linfo.def::Method
params, last_params = Base.unwrap_unionall(m.sig).parameters, Base.unwrap_unionall(last_m.sig).parameters

if last_m.nkw != 0
pos_sig_params = Base.rewrap_unionall(Tuple{last_params[(last_m.nkw+2):end]...}, last_m.sig).parameters
issame = true
if pos_sig_params == params
kept_frames[i] = false
end
end
if length(last_params) > length(params)
issame = true
for i = 1:length(params)
issame &= params[i] == last_params[i]
end
if issame
kept_frames[i] = false
end
end
end

# TODO: Detect more cases that can be collapsed
end
last_frame = frame
end
return trace[kept_frames]
end


function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true)
n = 0
last_frame = StackTraces.UNKNOWN
Expand Down Expand Up @@ -875,7 +942,9 @@ function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true)
if n > 0
push!(ret, (last_frame, n))
end
return _simplify_include_frames(ret)
trace = _simplify_include_frames(ret)
trace = _collapse_repeated_frames(trace)
return trace
end

function show_exception_stack(io::IO, stack)
Expand Down
40 changes: 40 additions & 0 deletions test/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -947,3 +947,43 @@ let buf = IOBuffer()
Base.show_method_candidates(buf, Base.MethodError(isa, ()), pairs((a = 5,)))
@test isempty(take!(buf))
end

f_internal_wrap(g, a; kw...) = error();
@inline f_internal_wrap(a; kw...) = f_internal_wrap(identity, a; kw...);
bt = try
f_internal_wrap(1)
catch
catch_backtrace()
end
@test !occursin("#f_internal_wrap#", sprint(Base.show_backtrace, bt))

g_collapse_pos(x, y=1.0, z=2.0) = error()
bt = try
g_collapse_pos(1.0)
catch
catch_backtrace()
end
bt_str = sprint(Base.show_backtrace, bt)
@test occursin("g_collapse_pos(x::Float64, y::Float64, z::Float64)", bt_str)
@test !occursin("g_collapse_pos(x::Float64)", bt_str)

g_collapse_kw(x; y=2.0) = error()
bt = try
g_collapse_kw(1.0)
catch
catch_backtrace()
end
bt_str = sprint(Base.show_backtrace, bt)
@test occursin("g_collapse_kw(x::Float64; y::Float64)", bt_str)
@test !occursin("g_collapse_kw(x::Float64)", bt_str)

g_collapse_pos_kw(x, y=1.0; z=2.0) = error()
bt = try
g_collapse_pos_kw(1.0)
catch
catch_backtrace()
end
bt_str = sprint(Base.show_backtrace, bt)
@test occursin("g_collapse_pos_kw(x::Float64, y::Float64; z::Float64)", bt_str)
@test !occursin("g_collapse_pos_kw(x::Float64, y::Float64)", bt_str)
@test !occursin("g_collapse_pos_kw(x::Float64)", bt_str)

2 comments on commit 703b3f8

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily package evaluation, I will reply here when finished:

@nanosoldier runtests(isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your package evaluation job has completed - possible new issues were detected.
A full report can be found here.

Please sign in to comment.