Skip to content

Commit 3276c11

Browse files
JeffBezansonNHDaly
andauthored
Restore StackOverflow error message for repeated frames (#39930)
Fixes backtrace printing to display the number of times a frame is repeated, if there is a frame that's duplicated several times. ```julia julia> function foo() foo() end foo (generic function with 1 method) julia> foo() ERROR: StackOverflowError: Stacktrace: [1] foo() (repeats 79984 times) @ Main ./REPL[16]:1 ``` Fixes #37587. Co-authored-by: Nathan Daly <nhdaly@gmail.com>
1 parent 53f328d commit 3276c11

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

base/errorshow.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -570,17 +570,17 @@ stacktrace_linebreaks()::Bool =
570570
tryparse(Bool, get(ENV, "JULIA_STACKTRACE_LINEBREAKS", "false")) === true
571571

572572
function show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
573-
n = length(trace)
574-
ndigits_max = ndigits(n)
573+
num_frames = length(trace)
574+
ndigits_max = ndigits(num_frames)
575575

576576
modulecolordict = copy(STACKTRACE_FIXEDCOLORS)
577577
modulecolorcycler = Iterators.Stateful(Iterators.cycle(STACKTRACE_MODULECOLORS))
578578

579579
println(io, "\nStacktrace:")
580580

581-
for (i, frame) in enumerate(trace)
582-
print_stackframe(io, i, frame, 1, ndigits_max, modulecolordict, modulecolorcycler)
583-
if i < n
581+
for (i, (frame, n)) in enumerate(trace)
582+
print_stackframe(io, i, frame, n, ndigits_max, modulecolordict, modulecolorcycler)
583+
if i < num_frames
584584
println(io)
585585
print_linebreaks && println(io)
586586
end
@@ -779,8 +779,7 @@ function show_backtrace(io::IO, t::Vector)
779779

780780
try invokelatest(update_stackframes_callback[], filtered) catch end
781781
# process_backtrace returns a Vector{Tuple{Frame, Int}}
782-
frames = map(x->first(x)::StackFrame, filtered)
783-
show_full_backtrace(io, frames; print_linebreaks = stacktrace_linebreaks())
782+
show_full_backtrace(io, filtered; print_linebreaks = stacktrace_linebreaks())
784783
return
785784
end
786785

test/errorshow.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ end
678678
@test getline(outputc) == getline(output0) + 2
679679
end
680680

681+
681682
# issue #30633
682683
@test_throws ArgumentError("invalid index: \"foo\" of type String") [1]["foo"]
683684
@test_throws ArgumentError("invalid index: nothing of type Nothing") [1][nothing]
@@ -763,3 +764,29 @@ let err = nothing
763764
@test !occursin("2d", err_str)
764765
end
765766
end
767+
768+
# issue #37587
769+
# TODO: enable on more platforms
770+
if Sys.isapple() || (Sys.islinux() && Sys.ARCH === :x86_64)
771+
single_repeater() = single_repeater()
772+
pair_repeater_a() = pair_repeater_b()
773+
pair_repeater_b() = pair_repeater_a()
774+
775+
@testset "repeated stack frames" begin
776+
let bt = try single_repeater()
777+
catch
778+
catch_backtrace()
779+
end
780+
bt_str = sprint(Base.show_backtrace, bt)
781+
@test occursin(r"repeats \d+ times", bt_str)
782+
end
783+
784+
let bt = try pair_repeater_a()
785+
catch
786+
catch_backtrace()
787+
end
788+
bt_str = sprint(Base.show_backtrace, bt)
789+
@test occursin(r"the last 2 lines are repeated \d+ more times", bt_str)
790+
end
791+
end
792+
end # Sys.isapple()

0 commit comments

Comments
 (0)