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

Warn about cycles in extension precompilation #53882

Closed
Show file tree
Hide file tree
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
10 changes: 8 additions & 2 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,12 @@ function run_extension_callbacks(pkgid::PkgId)
if extid.ntriggers == 0
# actually load extid, now that all dependencies are met,
# and record the result
if in(extid.id, precompilation_stack)
@warn """
Dependency cycle detected in extension precompilation: $(precompilation_stack_list()) > $(extid.id.name)
Loading $(extid.id.name) here will likely fail.
"""
end
succeeded = succeeded && run_extension_callbacks(extid)
succeeded || push!(EXT_DORMITORY_FAILED, extid)
end
Expand Down Expand Up @@ -2842,14 +2848,14 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
end

const precompilation_stack = Vector{PkgId}()
precompilation_stack_list() = join(map(p->p.name, precompilation_stack), " > ")
# Helpful for debugging when precompilation is unexpectedly nested.
# Enable with `JULIA_DEBUG=nested_precomp`. Note that it expected to be nested in classical code-load precompilation
# TODO: Add detection if extension precompilation is nested and error / return early?
function track_nested_precomp(pkgs::Vector{PkgId})
append!(precompilation_stack, pkgs)
if length(precompilation_stack) > 1
list() = join(map(p->p.name, precompilation_stack), " > ")
@debug "Nested precompilation: $(list())" _group=:nested_precomp
@debug "Nested precompilation: $(precompilation_stack_list())" _group=:nested_precomp
end
end

Expand Down
14 changes: 14 additions & 0 deletions test/extensions/circular/A/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name = "A"
uuid = "c8938445-7efa-411c-ba8f-721576f9f47a"
version = "0.1.0"

[deps]
B = "ef00b25e-dd85-47e0-9cd9-ed3c1ff51032"

[weakdeps]
C = "d95b043b-fbe6-48a2-93d2-75fba1b51518"
D = "64e66ba5-e914-4adb-a5f6-036ef0c801f3"

[extensions]
CExt = "C"
DExt = "D"
3 changes: 3 additions & 0 deletions test/extensions/circular/A/ext/CExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module CExt

end # module
3 changes: 3 additions & 0 deletions test/extensions/circular/A/ext/DExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module DExt

end # module
3 changes: 3 additions & 0 deletions test/extensions/circular/A/src/A.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module A

end # module
7 changes: 7 additions & 0 deletions test/extensions/circular/B/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name = "B"
uuid = "ef00b25e-dd85-47e0-9cd9-ed3c1ff51032"
version = "0.1.0"

[deps]
C = "d95b043b-fbe6-48a2-93d2-75fba1b51518"
D = "64e66ba5-e914-4adb-a5f6-036ef0c801f3"
3 changes: 3 additions & 0 deletions test/extensions/circular/B/src/B.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module B

end # module
3 changes: 3 additions & 0 deletions test/extensions/circular/C/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = "C"
uuid = "d95b043b-fbe6-48a2-93d2-75fba1b51518"
version = "0.1.0"
3 changes: 3 additions & 0 deletions test/extensions/circular/C/src/C.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module C

end # module
3 changes: 3 additions & 0 deletions test/extensions/circular/D/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = "D"
uuid = "64e66ba5-e914-4adb-a5f6-036ef0c801f3"
version = "0.1.0"
3 changes: 3 additions & 0 deletions test/extensions/circular/D/src/D.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module D

end # module
32 changes: 32 additions & 0 deletions test/extensions/circular/Manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This file is machine-generated - editing it directly is not advised

julia_version = "1.11.0-DEV"
manifest_format = "2.0"
project_hash = "6c189c4d9e1e9194c4a4d7627740c379ecff4942"

[[deps.A]]
deps = ["B"]
path = "./A"
uuid = "c8938445-7efa-411c-ba8f-721576f9f47a"
version = "0.1.0"
weakdeps = ["C", "D"]

[deps.A.extensions]
CExt = "C"
DExt = "D"

[[deps.B]]
deps = ["C", "D"]
path = "./B"
uuid = "ef00b25e-dd85-47e0-9cd9-ed3c1ff51032"
version = "0.1.0"

[[deps.C]]
path = "./C"
uuid = "d95b043b-fbe6-48a2-93d2-75fba1b51518"
version = "0.1.0"

[[deps.D]]
path = "./D"
uuid = "64e66ba5-e914-4adb-a5f6-036ef0c801f3"
version = "0.1.0"
5 changes: 5 additions & 0 deletions test/extensions/circular/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[deps]
A = "c8938445-7efa-411c-ba8f-721576f9f47a"
B = "ef00b25e-dd85-47e0-9cd9-ed3c1ff51032"
C = "d95b043b-fbe6-48a2-93d2-75fba1b51518"
D = "64e66ba5-e914-4adb-a5f6-036ef0c801f3"
13 changes: 13 additions & 0 deletions test/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,19 @@ end
finally
copy!(LOAD_PATH, old_load_path)
end

# issue 53081
@testset "avoid circular precompilation deadlock through extensions" begin
testenv = joinpath(@__DIR__, "extensions", "circular")
# TODO: avoid the error? https://github.com/JuliaLang/julia/pull/53112
# @test_warn (r"Dependency cycle detected in extension precompilation", r"Error during loading of extension") begin
run(ignorestatus(addenv(
`$(Base.julia_cmd()) --startup-file=no --project=$testenv -e 'using A'`,
"JULIA_TESTS" => nothing, # we want precompilepkgs to print for this, which it doesn't if this is set
"JULIA_DEPOT_PATH" => depot_path
)))
# end
end
finally
try
rm(depot_path, force=true, recursive=true)
Expand Down