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

Fix lack of robustness in stacktrace scrubbing #49633

Merged
Merged
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
7 changes: 4 additions & 3 deletions stdlib/Test/src/Test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,18 @@ function test_callsite(bt, file_ts, file_t)
# For that, we retrieve locations from lower to higher stack elements
# and only traverse parts of the backtrace which we haven't traversed before.
# The order will always be <internal functions> -> `@test` -> `@testset`.
internal = macrocall_location(bt, @__FILE__)::Int
internal = @something(macrocall_location(bt, @__FILE__), return nothing)
test = internal - 1 + findfirst(ip -> any(frame -> in_file(frame, file_t), StackTraces.lookup(ip)), @view bt[internal:end])::Int
serenity4 marked this conversation as resolved.
Show resolved Hide resolved
testset = test - 1 + macrocall_location(@view(bt[test:end]), file_ts)::Int
testset = test - 1 + @something(macrocall_location(@view(bt[test:end]), file_ts), return nothing)

# If stacktrace locations differ, include frames until the `@testset` appears.
test != testset && return testset
# `@test` and `@testset` occurred at the same stacktrace location.
# This may happen if `@test` occurred directly in scope of the testset,
# or if `@test` occurred in a function that has been inlined in the testset.
frames = StackTraces.lookup(bt[testset])
outer_frame = findfirst(frame -> in_file(frame, file_ts) && frame.func == Symbol("macro expansion"), frames)::Int
outer_frame = findfirst(frame -> in_file(frame, file_ts) && frame.func == Symbol("macro expansion"), frames)
isnothing(outer_frame) && return nothing
# The `@test` call occurred directly in scope of a `@testset`.
# The __source__ from `@test` will be printed in the test message upon failure.
# There is no need to include more frames, but always include at least the internal macrocall location in the stacktrace.
Expand Down