Skip to content

Commit

Permalink
Shift Cthulhu to extension
Browse files Browse the repository at this point in the history
- Require Julia 1.10+
- Add tests for registered error hints
- Test the Cthulhu extension
  • Loading branch information
timholy committed Dec 5, 2024
1 parent f57bcd1 commit 004e517
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 31 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
version: ['1.6', '1', 'pre']
version: ['1.10', '1', 'pre']
arch: [x64]
include:
- os: ubuntu-latest
prefix: xvfb-run
exclude:
- os: windows-latest
version: '1.6' # slow registry cloning on CI
version: '1.10' # slow registry cloning on CI
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
Expand Down
25 changes: 19 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ProfileView"
uuid = "c46f51b8-102a-5cf2-8d2c-8597cb0e0da7"
author = ["Tim Holy <[email protected]>"]
version = "1.8.1"
version = "1.9.0"

[deps]
Cairo = "159f3aea-2a34-519c-b102-8c37f9878175"
Expand All @@ -18,27 +18,40 @@ MethodAnalysis = "85b6ec6f-f7df-4429-9514-a64bcd9ee824"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
Profile = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[weakdeps]
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"

[extensions]
ProfileViewCthulhuExt = "Cthulhu"

[compat]
Cairo = "0.6, 0.8, 1"
Colors = "0.9, 0.10, 0.11, 0.12, 0.13"
Colors = "0.12, 0.13"
Dates = "1"
Cthulhu = "2"
FileIO = "1.6"
FlameGraphs = "0.2.10, 1"
Graphics = "0.4, 1"
Gtk4 = "0.5, 0.6, 0.7"
GtkObservables = "2"
InteractiveUtils = "1"
IntervalSets = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7"
MethodAnalysis = "0.4"
PrecompileTools = "1"
Preferences = "1.2"
Requires = "1"
julia = "1.6"
REPL = "1"
Profile = "1"
Test = "1"
UUIDs = "1"
julia = "1.10"

[extras]
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["AbstractTrees", "Test"]
test = ["AbstractTrees", "Cthulhu", "REPL", "Test"]
27 changes: 27 additions & 0 deletions ext/ProfileViewCthulhuExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module ProfileViewCthulhuExt

using ProfileView
using Cthulhu: Cthulhu

function ProfileView.descend_clicked(; optimize=false, iswarn=true, hide_type_stable=true, kwargs...)
st = ProfileView.clicked[]
if st === nothing || st.linfo === nothing
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
return nothing
end
return Cthulhu.descend(st.linfo; optimize, iswarn, hide_type_stable, kwargs...)
end
function ProfileView.ascend_clicked(; hide_type_stable=true, terminal=Cthulhu.default_terminal(), kwargs...)
st = ProfileView.clicked[]
if st === nothing || st.linfo === nothing
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
return nothing
end
if hasmethod(Cthulhu.buildframes, Tuple{Vector{StackTraces.StackFrame}})
return Cthulhu.ascend(terminal, ProfileView.clicked_trace[]; hide_type_stable, kwargs...)
else
return Cthulhu.ascend(terminal, st.linfo; hide_type_stable, kwargs...)
end
end

end
23 changes: 0 additions & 23 deletions src/ProfileView.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import GtkObservables: Canvas
import Cairo
using Graphics
using Preferences
using Requires

using FlameGraphs: Node, NodeData
const CONTROL = Gtk4.ModifierType_CONTROL_MASK
Expand Down Expand Up @@ -564,28 +563,6 @@ discardfirstcol(A) = A[:,2:end]
discardfirstcol(A::IndirectArray) = IndirectArray(A.index[:,2:end], A.values)

function __init__()
@require Cthulhu="f68482b8-f384-11e8-15f7-abe071a5a75f" begin
function descend_clicked(; optimize=false, iswarn=true, hide_type_stable=true, kwargs...)
st = clicked[]
if st === nothing || st.linfo === nothing
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
return nothing
end
return Cthulhu.descend(st.linfo; optimize, iswarn, hide_type_stable, kwargs...)
end
function ascend_clicked(; hide_type_stable=true, kwargs...)
st = clicked[]
if st === nothing || st.linfo === nothing
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
return nothing
end
if hasmethod(Cthulhu.buildframes, Tuple{Vector{StackTraces.StackFrame}})
return Cthulhu.ascend(clicked_trace[]; hide_type_stable, kwargs...)
else
return Cthulhu.ascend(st.linfo; hide_type_stable, kwargs...)
end
end
end
Base.Experimental.register_error_hint(MethodError) do io, exc, argtypes, kwargs
if (exc.f === descend_clicked || exc.f === ascend_clicked) && isempty(argtypes)
printstyled(io, "\n`using Cthulhu` is required for `$(exc.f)`"; color=:yellow)
Expand Down
53 changes: 53 additions & 0 deletions test/extensions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using ProfileView
using Cthulhu
if !isdefined(@__MODULE__, :fake_terminal)
@eval (@__MODULE__) begin
include(joinpath(pkgdir(Cthulhu), "test", "FakeTerminals.jl"))
using .FakeTerminals
macro with_try_stderr(out, expr)
quote
try
$(esc(expr))
catch err
bt = catch_backtrace()
Base.display_error(stderr, err, bt)
#close($(esc(out)))
end
end
end
end
end
using Test

@testset "Extensions" begin
@testset "Cthulhu" begin
cread1(io) = readuntil(io, ''; keep=true)
cread(io) = cread1(io) * cread1(io)

# profile_test(1) # defined in test/runtests.jl
# @profile profile_test(10)
_, bt = add2(Any[1,2])
st = stacktrace(bt)
ProfileView.clicked[] = st[1]
fake_terminal() do term, in, out, _
t = @async begin
@with_try_stderr out descend_clicked(; interruptexc=false, terminal=term)
end
lines = cread(out)
@test occursin("Select a call to descend into", lines)
write(in, 'q')
wait(t)
end
ProfileView.clicked_trace[] = st
fake_terminal() do term, in, out, _
t = @async begin
@with_try_stderr out ascend_clicked(; interruptexc=false, terminal=term)
end
lines = readuntil(out, 'q'; keep=true) # up to the "q to quit" prompt
@test occursin("Choose a call for analysis", lines)
write(in, 'q')
write(in, 'q')
wait(t)
end
end
end
11 changes: 11 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ end

@test isa(ProfileView.view(nothing), ProfileView.GtkWindow)

ProfileView.closeall()

# Interactivity
stackframe(func, file, line; C=false) = ProfileView.StackFrame(Symbol(func), Symbol(file), line, nothing, C, false, 0)

Expand Down Expand Up @@ -180,4 +182,13 @@ end
ProfileView.clicked[] = st[idx]
@test_logs (:warn, "click on a non-inlined bar to see `code_warntype` info") warntype_clicked(io) === nothing
end

@testset "error hints" begin
if !isdefined(@__MODULE__, :Cthulhu)
@test_throws "`using Cthulhu` is required" ProfileView.descend_clicked()
@test_throws "`using Cthulhu` is required" ProfileView.ascend_clicked()
end
end
end

include("extensions.jl")

0 comments on commit 004e517

Please sign in to comment.