linkage_checker: check variable references with dlopen
The linkage check currently does nothing to check the validity of variable-referenced libraries (prefixed with an `@`). We could rectify that by mimicking the dynamic linker in looking up the variable-referenced library, but this could get quite complicated. Instead, let's let the linker do the hard work by checking if we can `dlopen` libraries and bundles that contain variable linkage. The `dlopen` will fail if the linker cannot resolve the variable reference. There are at least two disadvantages to this approach relative to the alternative suggested above: 1. This doesn't work for binary executables. 2. This doesn't identify which variable references are broken. It's still better than not checking them at all, which is what we do currently, and saves us from having to carry around code that parses and verifies variable references directly.
This commit is contained in:
parent
1f0ab4a1ee
commit
0191a275cc
@ -32,6 +32,7 @@ class LinkageChecker
|
||||
@unnecessary_deps = []
|
||||
@unwanted_system_dylibs = []
|
||||
@version_conflict_deps = []
|
||||
@broken_variable_dylibs = []
|
||||
|
||||
check_dylibs(rebuild_cache: rebuild_cache)
|
||||
end
|
||||
@ -46,6 +47,7 @@ class LinkageChecker
|
||||
display_items "Undeclared dependencies with linkage", @undeclared_deps
|
||||
display_items "Dependencies with no linkage", @unnecessary_deps
|
||||
display_items "Unwanted system libraries", @unwanted_system_dylibs
|
||||
display_items "Libraries with broken variable references", @broken_variable_dylibs
|
||||
end
|
||||
|
||||
def display_reverse_output
|
||||
@ -68,11 +70,12 @@ class LinkageChecker
|
||||
display_items "Broken dependencies", @broken_deps, puts_output: puts_output
|
||||
display_items "Unwanted system libraries", @unwanted_system_dylibs, puts_output: puts_output
|
||||
display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output
|
||||
display_items "Libraries with broken variable references", @broken_variable_dylibs, puts_output: puts_output
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def broken_library_linkage?
|
||||
issues = [@broken_deps, @unwanted_system_dylibs, @version_conflict_deps]
|
||||
issues = [@broken_deps, @unwanted_system_dylibs, @version_conflict_deps, @broken_variable_dylibs]
|
||||
[issues, unexpected_broken_dylibs, unexpected_present_dylibs].flatten.any?(&:present?)
|
||||
end
|
||||
|
||||
@ -148,6 +151,7 @@ class LinkageChecker
|
||||
end
|
||||
|
||||
checked_dylibs = Set.new
|
||||
dlopened_if_needed_files = Set.new
|
||||
|
||||
keg_files_dylibs.each do |file, dylibs|
|
||||
dylibs.each do |dylib|
|
||||
@ -159,6 +163,15 @@ class LinkageChecker
|
||||
|
||||
if dylib.start_with? "@"
|
||||
@variable_dylibs << dylib
|
||||
|
||||
if dlopened_if_needed_files.add?(file)
|
||||
file = Pathname.new(file)
|
||||
next if file.binary_executable?
|
||||
next if dylib_found_via_dlopen(file.dylib_id)
|
||||
|
||||
@broken_variable_dylibs << file.dylib_id
|
||||
end
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user