1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
# This file is a part of Julia. License is MIT: https://julialang.org/license
# Test location information for inlined code (ref issues #1334 #12544)
module test_inline_bt
using Test
function get_bt_frames(functionname, bt)
for i = 1:length(bt)
lkup = Base.StackTraces.lookup(bt[i])
lkup[end].func == functionname && (return lkup)
end
end
# same-file inline
eval(Expr(:function, Expr(:call, :test_inline_1),
Expr(:block, Expr(:line, 99, Symbol("backtrace.jl")),
Expr(:block, Expr(:line, 42),
Expr(:meta, :push_loc, Symbol("backtrace.jl"), :inlfunc),
Expr(:line, 37),
Expr(:call, :throw, "foo"),
Expr(:meta, :pop_loc),
Expr(:line, 99)))))
@test functionloc(test_inline_1) == ("backtrace.jl", 99)
try
test_inline_1()
error("unexpected")
catch err
lkup = get_bt_frames(:test_inline_1, catch_backtrace())
@test length(lkup) == 2
@test endswith(string(lkup[2].file), "backtrace.jl")
@test lkup[2].line == 42
# TODO: we don't support surface AST locations with inlined function names
@test_broken lkup[1].func == :inlfunc
@test endswith(string(lkup[1].file), "backtrace.jl")
@test lkup[1].line == 37
end
# different-file inline
const absfilepath = Sys.iswindows() ? "C:\\foo\\bar\\baz.jl" : "/foo/bar/baz.jl"
eval(Expr(:function, Expr(:call, :test_inline_2),
Expr(:block, Expr(:line, 81, Symbol("backtrace.jl")),
Expr(:block, Expr(:meta, :push_loc, Symbol(absfilepath)),
Expr(:line, 111),
Expr(:call, :throw, "foo"),
Expr(:meta, :pop_loc),
Expr(:line, 99)))))
@test functionloc(test_inline_2) == ("backtrace.jl", 81)
try
test_inline_2()
error("unexpected")
catch err
lkup = get_bt_frames(:test_inline_2, catch_backtrace())
@test length(lkup) == 2
@test endswith(string(lkup[2].file), "backtrace.jl")
@test lkup[2].line == 81
@test string(lkup[1].file) == absfilepath
@test lkup[1].line == 111
end
end # module
#issue 12977: line numbers for kwarg methods.
linenum = @__LINE__; f12977(; args...) = ()
loc = functionloc(f12977)
@test endswith(loc[1], "backtrace.jl")
@test loc[2] == linenum
@noinline function test_throw_commoning(x)
if x==1; throw(AssertionError()); end
if x==2; throw(AssertionError()); end
end
let
local b1, b2
try
test_throw_commoning(1)
catch
b1 = stacktrace(catch_backtrace())
end
try
test_throw_commoning(2)
catch
b2 = stacktrace(catch_backtrace())
end
i1 = findfirst(frame -> frame.func === :test_throw_commoning, b1)
i2 = findfirst(frame -> frame.func === :test_throw_commoning, b2)
@test i1 > 0 && i2 > 0
@test b1[i1].line != b2[i2].line
end
module BackTraceTesting
using Test
@inline bt2() = backtrace()
@inline bt1() = bt2()
bt() = bt1()
lkup = map(StackTraces.lookup, bt())
hasbt = hasbt2 = false
for sfs in lkup
for sf in sfs
if sf.func == :bt
global hasbt = true
end
if sf.func == :bt2
global hasbt2 = true
end
end
end
@test hasbt
@test hasbt2
function btmacro()
ret = @timed backtrace()
ret[1]
end
lkup = map(StackTraces.lookup, btmacro())
hasme = hasbtmacro = false
for sfs in lkup
for sf in sfs
if sf.func == Symbol("macro expansion")
global hasme = true
end
if sf.func == :btmacro
global hasbtmacro = true
end
end
end
@test hasme
@test hasbtmacro
end
# Interpreter backtraces
bt = eval(quote
try
error()
catch
catch_backtrace()
end
end)
lkup = map(StackTraces.lookup, bt)
hastoplevel = false
for sfs in lkup
for sf in sfs
if sf.linfo isa Core.CodeInfo
global hastoplevel = true
end
end
end
@test hastoplevel
# issue #23971
let
for i = 1:1
global bt23971 = backtrace()
end
end
let st = stacktrace(bt23971)
@test StackTraces.is_top_level_frame(st[1])
@test string(st[1].file) == @__FILE__
@test !occursin("missing", string(st[2].file))
end
# issue #27959
let bt, found = false
@testset begin
bt = backtrace()
end
for frame in map(StackTraces.lookup, bt)
if frame[1].line == @__LINE__() - 3 && frame[1].file == Symbol(@__FILE__)
found = true; break
end
end
@test found
end
# issue 28618
let bt, found = false
@info ""
bt = backtrace()
for frame in map(StackTraces.lookup, bt)
if frame[1].line == @__LINE__() - 2 && frame[1].file == Symbol(@__FILE__)
found = true; break
end
end
@test found
end
|