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
|
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Test, Profile, Serialization
Profile.clear()
Profile.init()
let iobuf = IOBuffer()
for fmt in (:tree, :flat)
Test.@test_logs (:warn, r"^There were no samples collected\.") Profile.print(iobuf, format=fmt, C=true)
Test.@test_logs (:warn, r"^There were no samples collected\.") Profile.print(iobuf, [0x0000000000000001], Dict(0x0000000000000001 => [Base.StackTraces.UNKNOWN]), format=fmt, C=false)
end
end
@noinline function busywait(t, n_tries)
iter = 0
init_data = Profile.len_data()
while iter < n_tries && Profile.len_data() == init_data
iter += 1
tend = time_ns() + 1e9 * t
while time_ns() < tend end
end
end
busywait(0, 0) # compile
@profile busywait(1, 20)
let r = Profile.retrieve()
mktemp() do path, io
serialize(io, r)
close(io)
open(path) do io
@test isa(deserialize(io), Tuple{Vector{UInt},Dict{UInt64,Vector{Base.StackTraces.StackFrame}}})
end
end
end
let iobuf = IOBuffer()
Profile.print(iobuf, format=:tree, C=true)
str = String(take!(iobuf))
@test !isempty(str)
truncate(iobuf, 0)
Profile.print(iobuf, format=:tree, maxdepth=2)
str = String(take!(iobuf))
@test !isempty(str)
truncate(iobuf, 0)
Profile.print(iobuf, format=:flat, C=true)
str = String(take!(iobuf))
@test !isempty(str)
truncate(iobuf, 0)
Profile.print(iobuf)
@test !isempty(String(take!(iobuf)))
truncate(iobuf, 0)
Profile.print(iobuf, format=:flat, sortedby=:count)
@test !isempty(String(take!(iobuf)))
Profile.print(iobuf, format=:tree, recur=:flat)
str = String(take!(iobuf))
@test !isempty(str)
truncate(iobuf, 0)
end
Profile.clear()
@test isempty(Profile.fetch())
let
@test Profile.callers("\\") !== nothing
@test Profile.callers(\) !== nothing
# linerange with no filename provided should fail
@test_throws ArgumentError Profile.callers(\; linerange=10:50)
end
# issue #13229
module I13229
using Test, Profile
global z = 0
@timed @profile for i = 1:5
function f(x)
return x + i
end
global z = f(i)
end
@test z == 10
end
@testset "setting sample count and delay in init" begin
n_, delay_ = Profile.init()
@test n_ == 1_000_000
def_delay = Sys.iswindows() ? 0.01 : 0.001
@test delay_ == def_delay
Profile.init(n=1_000_001, delay=0.0005)
n_, delay_ = Profile.init()
@test n_ == 1_000_001
@test delay_ == 0.0005
Profile.init(n=1_000_000, delay=def_delay)
end
@testset "Line number correction" begin
@profile busywait(1, 20)
_, fdict0 = Profile.flatten(Profile.retrieve()...)
Base.update_stackframes_callback[] = function(list)
modify((sf, n)) = sf.func == :busywait ? (StackTraces.StackFrame(sf.func, sf.file, sf.line+2, sf.linfo, sf.from_c, sf.inlined, sf.pointer), n) : (sf, n)
map!(modify, list, list)
end
_, fdictc = Profile.flatten(Profile.retrieve()...)
Base.update_stackframes_callback[] = identity
function getline(sfs)
for sf in sfs
sf.func == :busywait && return sf.line
end
nothing
end
@test getline(values(fdictc)) == getline(values(fdict0)) + 2
end
# Profile deadlocking in compilation (debuginfo registration)
let cmd = Base.julia_cmd()
script = """
using Profile
f(::Val) = GC.safepoint()
@profile for i = 1:10^3; f(Val(i)); end
print(Profile.len_data())
"""
p = open(`$cmd -e $script`)
t = Timer(120) do t
# should be under 10 seconds, so give it 2 minutes then report failure
println("KILLING BY PROFILE TEST WATCHDOG\n")
kill(p, Base.SIGTERM)
sleep(10)
kill(p, Base.SIGKILL)
end
s = read(p, String)
close(t)
@test success(p)
@test parse(Int, s) > 1000
end
|