Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fine-tune stacktrace printing #37773

Merged
merged 4 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions base/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,9 @@ function replaceuserpath(str)
return str
end

const STACKTRACE_MODULECOLORS = [:light_blue, :light_yellow,
:light_magenta, :light_green, :light_cyan, :light_red,
:blue, :yellow, :magenta, :green, :cyan, :red]
const STACKTRACE_MODULECOLORS = [:magenta, :cyan, :green, :yellow]
const STACKTRACE_FIXEDCOLORS = IdDict(Base => :light_black, Core => :light_black)

stacktrace_expand_basepaths()::Bool =
tryparse(Bool, get(ENV, "JULIA_STACKTRACE_EXPAND_BASEPATHS", "false")) === true
stacktrace_contract_userdir()::Bool =
Expand All @@ -576,7 +576,7 @@ function show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
n = length(trace)
ndigits_max = ndigits(n)

modulecolordict = Dict{Module, Symbol}()
modulecolordict = copy(STACKTRACE_FIXEDCOLORS)
modulecolorcycler = Iterators.Stateful(Iterators.cycle(STACKTRACE_MODULECOLORS))

println(io, "\nStacktrace:")
Expand Down
31 changes: 22 additions & 9 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2064,7 +2064,8 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg
if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) &&
isdefined(uw.name.module, uw.name.mt.name) &&
ft == typeof(getfield(uw.name.module, uw.name.mt.name))
show_sym(io, (demangle ? demangle_function_name : identity)(uw.name.mt.name))
s = sprint(show_sym, (demangle ? demangle_function_name : identity)(uw.name.mt.name), context=io)
print_within_stacktrace(io, s, bold=true)
elseif isa(ft, DataType) && ft.name === Type.body.name &&
(f = ft.parameters[1]; !isa(f, TypeVar))
uwf = unwrap_unionall(f)
Expand All @@ -2076,19 +2077,20 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg
if html
print(io, "($fargname::<b>", ft, "</b>)")
else
print(io, "($fargname::", ft, ")")
print_within_stacktrace(io, "($fargname::", ft, ")", bold=true)
end
end
nothing
end

function print_within_stacktrace(io, s...; color, bold=false)
function print_within_stacktrace(io, s...; color=:normal, bold=false)
if get(io, :backtrace, false)::Bool
printstyled(io, s...; color, bold)
else
print(io, s...)
end
end

function show_tuple_as_call(io::IO, name::Symbol, sig::Type, demangle=false, kwargs=nothing, argnames=nothing)
# print a method signature tuple for a lambda definition
if sig === Tuple
Expand All @@ -2105,33 +2107,44 @@ function show_tuple_as_call(io::IO, name::Symbol, sig::Type, demangle=false, kwa
sig = (sig::DataType).parameters
show_signature_function(env_io, sig[1], demangle)
first = true
print_within_stacktrace(io, "(", color=:light_black)
print(io, "(")
mcabbott marked this conversation as resolved.
Show resolved Hide resolved
show_argnames = argnames !== nothing && length(argnames) == length(sig)
for i = 2:length(sig) # fixme (iter): `eachindex` with offset?
first || print(io, ", ")
first = false
if show_argnames
print_within_stacktrace(io, argnames[i]; bold=true, color=:light_black)
print_within_stacktrace(io, argnames[i]; color=:light_black)
end
print(io, "::")
print_within_stacktrace(env_io, sig[i]; color=:light_black)
print_type_stacktrace(env_io, sig[i])
end
if kwargs !== nothing
print(io, "; ")
first = true
for (k, t) in kwargs
first || print(io, ", ")
first = false
print_within_stacktrace(io, k; bold=true, color=:light_black)
print_within_stacktrace(io, k; color=:light_black)
print(io, "::")
print_within_stacktrace(io, t; color=:light_black)
print_type_stacktrace(io, t)
end
end
print_within_stacktrace(io, ")", color=:light_black)
print_within_stacktrace(io, ")", bold=true)
show_method_params(io, tv)
nothing
end

function print_type_stacktrace(io, type; color=:normal)
str = sprint(show, type, context=io)
i = findfirst('{', str)
Copy link
Contributor Author

@mcabbott mcabbott Sep 27, 2020

Choose a reason for hiding this comment

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

This seems a bit crude, but I got lost trying to find the right printing function to overload for this purpose (of printing only the type parameters dimly, not the outermost type). It should still use aliases like Matrix{Int}.

It's also possible this should be a method of print_within_stacktrace instead of its own function.

if isnothing(i) || !get(io, :backtrace, false)::Bool
printstyled(io, str; color=color)
else
printstyled(io, str[1:i-1]; color=color)
printstyled(io, str[i:end]; color=:light_black)
end
end

resolvebinding(@nospecialize(ex)) = ex
resolvebinding(ex::QuoteNode) = ex.value
resolvebinding(ex::Symbol) = resolvebinding(GlobalRef(Main, ex))
Expand Down
2 changes: 1 addition & 1 deletion base/stacktraces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ function show_spec_linfo(io::IO, frame::StackFrame)
elseif frame.func === top_level_scope_sym
print(io, "top-level scope")
else
print(io, Base.demangle_function_name(string(frame.func)))
Base.print_within_stacktrace(io, Base.demangle_function_name(string(frame.func)), bold=true)
end
elseif linfo isa MethodInstance
def = linfo.def
Expand Down