From 72d3abeb0e86ec3a8689bad199801720e2e05fb5 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 7 Feb 2024 22:28:09 +0100 Subject: [PATCH] Fix potential instability/invalidation in dlpath (#53232) While debugging some invalidations and instabilities in code in packages I work on, one of the issues I stumbled over is this code in this `dlpath` method: ```julia function dlpath(libname::Union{AbstractString, Symbol}) handle = dlopen(libname) path = dlpath(handle) dlclose(handle) return path end ``` The `dlopen` modified in this PR can in principle return `nothing`. But there is no `dlpath` method for this. If one loads just a plain Julia, all is fine, but under certain conditions (deep in a call chain analyzed with Cthulhu.jl) it ended up not being able to prove that `path` will be a string, and only inferred it as `Any`. But if `throw_error` is set to `true` (the default, and used in the relevant code path) then `dlopen` cannot return `nothing`, it always returns a `String`. But the Julia compiler can't know that, as the exception is thrown by a C helper. So instead modify the Julia code a bit to help Julia deduce this fact by itself. --- base/libdl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/libdl.jl b/base/libdl.jl index 38dd86ca55f62..bd909bb7b90eb 100644 --- a/base/libdl.jl +++ b/base/libdl.jl @@ -118,7 +118,7 @@ dlopen(s::Symbol, flags::Integer = default_rtld_flags; kwargs...) = function dlopen(s::AbstractString, flags::Integer = default_rtld_flags; throw_error::Bool = true) ret = ccall(:jl_load_dynamic_library, Ptr{Cvoid}, (Cstring,UInt32,Cint), s, flags, Cint(throw_error)) - if ret == C_NULL + if !throw_error && ret == C_NULL return nothing end return ret