Revision a311f4d8327a5051b11a6bcd1c44ed931d4ab261 authored by Jacob Quinn on 20 October 2022, 02:44:43 UTC, committed by GitHub on 20 October 2022, 02:44:43 UTC
As reported [here](https://discourse.julialang.org/t/test-failures-for-sockets-base-runtests-sockets/88898). My guess on the original issue reported is that, for some reason, the host where the tests are run is unable to listen on any ports, so we end up cycling through the entire UInt16 range (the test starts at port 11011), but when we fail on port 65535, we do `addr.port + 1` and instead of wrapping around as I believe this function intends to happen (as noted by the `addr.port == default_port` check before we error), it gets promoted to `Int(65536)` which then throws an (unexpected) error in the `InetAddr` constructor. I'm not quite sure how to test this exactly though, because we'd need to simulate not being able to listen on any ports? If anyone has any ideas, I'm all ears.
1 parent 0d52506
backtrace.jl
# This file is a part of Julia. License is MIT: https://julialang.org/license
import Base.StackTraces: lookup
# Test location information for inlined code (ref issues #1334 #12544)
module test_inline_bt
using Test
import ..lookup
function get_bt_frames(functionname, bt)
for i = 1:length(bt)
lkup = lookup(bt[i])
lkup[end].func == functionname && return lkup
end
return StackTraces.StackFrame[]
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
import ..lookup
@inline bt2() = backtrace()
@inline bt1() = bt2()
bt() = bt1()
lkup = map(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(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(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(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
@debug ""
bt = backtrace()
for frame in map(lookup, bt)
if frame[1].line == @__LINE__() - 2 && frame[1].file === Symbol(@__FILE__)
found = true; break
end
end
@test found
end
# Syntax error locations appear in backtraces
let trace = try
include_string(@__MODULE__,
"""
)
""", "a_filename")
catch
stacktrace(catch_backtrace())
end
@test trace[1].func === Symbol("top-level scope")
@test trace[1].file === :a_filename
@test trace[1].line == 2
end
let trace = try
include_string(@__MODULE__,
"""
incomplete_syntax(
""", "a_filename")
catch
stacktrace(catch_backtrace())
end
@test trace[1].func === Symbol("top-level scope")
@test trace[1].file === :a_filename
@test trace[1].line == 2
end
# issue #45171
linenum = @__LINE__; function f45171(;kwarg = true)
1
error()
end
let trace = try
f45171()
catch
stacktrace(catch_backtrace())
end
@test trace[3].line == linenum
end
# issue #29695 (see also test for #28442)
let code = """
f29695(c) = g29695(c)
g29695(c) = c >= 1000 ? (return backtrace()) : f29695(c + 1)
bt = f29695(1)
meth_names = [ip.code.def.name for ip in bt
if ip isa Base.InterpreterIP && ip.code isa Core.MethodInstance]
num_fs = sum(meth_names .== :f29695)
num_gs = sum(meth_names .== :g29695)
print(num_fs, ' ', num_gs)
"""
@test read(`$(Base.julia_cmd()) --startup-file=no --compile=min -e $code`, String) == "1000 1000"
end
# Test that modules make it into InterpreterIP for top-level code
let code = """
module A
foo() = error("Expected")
try
foo()
catch
global bt = catch_backtrace()
end
end
foreach(println, A.bt)
"""
bt_str = read(`$(Base.julia_cmd()) --startup-file=no --compile=min -e $code`, String)
@test occursin(r"InterpreterIP in MethodInstance for .*A\.foo", bt_str)
@test occursin("InterpreterIP in top-level CodeInfo for Main.A", bt_str)
end
"""
_reformat_sp(bt_data...) -> sp::Vector{Ptr{Cvoid}}
Convert the output `bt_data` of `jl_backtrace_from_here` with `returnsp` flag set to a
vector of valid stack pointers `sp`; i.e., `sp` is a subset of `bt_data[3]`.
See also `Base._reformat_bt`.
"""
function _reformat_sp(
bt_raw::Array{Ptr{Cvoid},1},
bt2::Array{Any,1},
sp_raw::Array{Ptr{Cvoid},1},
)
bt = Base._reformat_bt(bt_raw, bt2)
sp = empty!(similar(sp_raw))
i = j = 0
while true
# Advance `i` such that `bt[i] isa Ptr{Cvoid}` (native pointer).
local ip
while true
if i == lastindex(bt)
return sp
end
i += 1
x = bt[i]
if x isa Ptr{Cvoid}
ip = x
break
end
end
# Advance `j` such that `bt_raw[j] == bt[i]` to find a valid stack pointer.
while true
if j == lastindex(bt_raw)
return sp
end
j += 1
if bt_raw[j] == ip
push!(sp, sp_raw[j])
break
end
end
end
end
"""
withframeaddress(f)
Call function `f` with an address `ptr::Ptr{Cvoid}` of an independent frame
immediately outer to `f`.
"""
withframeaddress
@eval @noinline function withframeaddress(f)
sp = Core.Intrinsics.llvmcall(
($"""
declare i8* @llvm.frameaddress(i32)
define private i$(Sys.WORD_SIZE) @frameaddr() {
%1 = call i8* @llvm.frameaddress(i32 0)
%2 = ptrtoint i8* %1 to i$(Sys.WORD_SIZE)
ret i$(Sys.WORD_SIZE) %2
}""", "frameaddr"),
UInt,
Tuple{},
)
@noinline f(Ptr{Cvoid}(sp))
end
function sandwiched_backtrace()
local ptr1, ptr2, bt
withframeaddress() do p1
ptr1 = p1
bt = ccall(:jl_backtrace_from_here, Ref{Base.SimpleVector}, (Cint, Cint), true, 0)
withframeaddress() do p2
ptr2 = p2
end
end
return ptr1, ptr2, bt
end
@testset "stack pointers" begin
ptr1, ptr2, bt_data = sandwiched_backtrace()
sp = _reformat_sp(bt_data...)
@test ptr2 < sp[2]
@test sp[1] < ptr1
@test all(diff(Int128.(UInt.(sp))) .> 0)
end
Computing file changes ...