Skip to content

Commit

Permalink
Consolidate find_visible_frames and re-enable public frames for 1.9/1.10
Browse files Browse the repository at this point in the history
  • Loading branch information
BioTurboNick committed Sep 27, 2023
1 parent 743f8c0 commit e8b618c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 75 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "AbbreviatedStackTraces"
uuid = "ac637c84-cc71-43bf-9c33-c1b4316be3d4"
authors = ["Nicholas Bauer <[email protected]>"]
version = "0.2.1"
version = "0.2.2"

[deps]
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
Expand Down
91 changes: 17 additions & 74 deletions src/AbbreviatedStackTraces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,77 +49,24 @@ is_broadcast(path) = startswith(path, r".[/\\]broadcast.jl")
# 9. Remove the topmost frame if it's a REPL toplevel.
# 10. Remove a broadcast materialize frame if it's the topmost frame.
function find_visible_frames(trace::Vector)
user_frames_i = findall(trace) do frame
file = String(frame[1].file)
!is_julia(file) && !is_ide_support(file)
public_frames_i = if parse(Bool, get(ENV, "JULIA_STACKTRACE_PUBLIC", "false"))
pfi = findall(trace) do frame
framemodule = parentmodule(frame[1])
framemodule === nothing && return false
module_public_names = names(framemodule)
frame[1].func module_public_names
end
pfi !== nothing ? pfi : Int[]
else
Int[]
end

# construct set of visible modules
all_modules = convert(Vector{Module}, filter!(!isnothing, unique(t[1] |> parentmodule for t trace)))
user_modules = convert(Vector{Module}, filter!(!isnothing, unique(t[1] |> parentmodule for t @view trace[user_frames_i])))
Main user_modules || push!(user_modules, Main)

debug_entries = split(get(ENV, "JULIA_DEBUG", ""), ",")
debug_include = filter(x -> !startswith(x, "!"), debug_entries)
debug_exclude = lstrip.(filter!(x -> startswith(x, "!"), debug_entries), '!')

debug_include_modules = filter(m -> string(m) debug_include, all_modules)
debug_exclude_modules = filter(m -> string(m) debug_exclude, all_modules)
setdiff!(union!(user_modules, debug_include_modules), debug_exclude_modules)

# construct set of visible frames
visible_frames_i = findall(trace) do frame
file = String(frame[1].file)
filenamebase = file |> basename |> splitext |> first
mod = parentmodule(frame[1])
return (mod user_modules || filenamebase debug_include) &&
!(filenamebase debug_exclude) ||
is_top_level_frame(frame[1]) && is_repl(file) ||
user_frames_i = let
ufi = findall(trace) do frame
file = String(frame[1].file)
!is_julia(file) && !is_ide_support(file)
end

# add one additional frame above each contiguous set of user code frames, removing 0.
filter!(>(0), sort!(union!(visible_frames_i, visible_frames_i .- 1)))

# remove Main frames that originate from internal code (e.g. BenchmarkTools)
filter!(i -> parentmodule(trace[i][1]) != Main || !is_julia(string(trace[i][1].file)), visible_frames_i)

# for each appearance of an already-visible `materialize` broadcast frame, include
# the next immediate hidden frame after the last `broadcast` frame
broadcasti = []
for i visible_frames_i
trace[i][1].func == :materialize || continue
push!(broadcasti, findlast(trace[1:i - 1]) do frame
!is_broadcast(String(frame[1].file))
end)
end
sort!(union!(visible_frames_i, filter!(!isnothing, broadcasti)))

if length(visible_frames_i) > 0 && visible_frames_i[end] == length(trace)
# remove REPL-based top-level
# note: file field for top-level is different from the rest, doesn't include ./
startswith(String(trace[end][1].file), "REPL") && pop!(visible_frames_i)
end

if length(visible_frames_i) == 1 && trace[only(visible_frames_i)][1].func == :materialize
# remove a materialize frame if it is the only visible frame
pop!(visible_frames_i)
end

return visible_frames_i
end

function find_visible_frames_public(trace::Vector)
public_frames_i = findall(trace) do frame
framemodule = parentmodule(frame[1])
framemodule === nothing && return false
module_public_names = names(framemodule)
frame[1].func module_public_names
end

user_frames_i = findall(trace) do frame
file = String(frame[1].file)
!is_julia(file) && !is_ide_support(file)
end
ufi !== nothing ? ufi : Int[]
end

# construct set of visible modules
Expand Down Expand Up @@ -236,12 +183,8 @@ function show_compact_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
end
end

# select frames from user-controlled code
if VERSION >= v"1.11.0-DEV.511"
is = parse(Bool, get(ENV, "JULIA_STACKTRACE_PUBLIC", "false")) ? find_visible_frames_public(trace) : find_visible_frames(trace)
else
is = find_visible_frames(trace)
end
# select frames from user-controlled code and optionally public frames
is = find_visible_frames(trace)

num_vis_frames = length(is)

Expand Down

2 comments on commit e8b618c

@BioTurboNick
Copy link
Owner Author

Choose a reason for hiding this comment

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

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/92340

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.2 -m "<description of version>" e8b618ca5ea761dfc88b527d338ea09928dc327a
git push origin v0.2.2

Please sign in to comment.