-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dlopen should follow platform default behavior
For OSX the default behavior is to dlopen with RTLD_GLOBAL while on most other POSIX platforms the default is RTLD_LOCAL. This reverts the behavior introduced in #11352 which made RTLD_LOCAL the default for all platforms which caused issues when loading shared libraries on OSX. This PR also cleans up some `Libdl` behavior and adds tests for the `Libdl` module. `Libdl.dlopen` now prints a detailed error message in the thrown exception rather than printing to STDERR. `Libdl.dlsym` now throws an exception instead of printing an error message to STDERR if the symbol is not found in the shared library. `RTLD_*` enum values now start at 1 instead of 0 to reflect the fact that RTLD_LOCAL is not universal default behavior on all POSIX platforms and needs to be detected on OSX. cc: @vtjnash, @poulson closes #11692 fixes #11689
- Loading branch information
1 parent
1368cae
commit 595058b
Showing
7 changed files
with
131 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# these could fail on an embedded installation | ||
# but for now, we don't handle that case | ||
dlls = Libdl.dllist() | ||
@test !isempty(dlls) | ||
@test length(dlls) > 3 # at a bare minimum, probably have some version of libstdc, libgcc, libjulia, ... | ||
if @unix? true : (Base.windows_version() >= Base.WINDOWS_VISTA_VER) | ||
for dl in dlls | ||
if isfile(dl) && (Libdl.dlopen_e(dl) != C_NULL) | ||
@test Base.samefile(Libdl.dlpath(dl), dl) | ||
end | ||
end | ||
end | ||
@test length(filter(dlls) do dl | ||
return ismatch(Regex("^libjulia(?:.*)\.$(Libdl.dlext)(?:\..+)?\$"), basename(dl)) | ||
end) == 1 # look for something libjulia-like (but only one) | ||
|
||
# library handle pointer must not be NULL | ||
@test_throws ArgumentError Libdl.dlsym(C_NULL, :foo) | ||
@test_throws ArgumentError Libdl.dlsym_e(C_NULL, :foo) | ||
|
||
@test !isempty(Libdl.find_library(["libccalltest"], [dirname(@__FILE__)])) | ||
|
||
# dlopen should be able to handle absolute and relative paths, with and without dlext | ||
let dl = Libdl.dlopen_e(abspath("./libccalltest")) | ||
@test dl != C_NULL | ||
Libdl.dlclose(dl) | ||
end | ||
|
||
let dl = Libdl.dlopen_e(join((abspath("./libccalltest"), string(".", Libdl.dlext)))) | ||
@test dl != C_NULL | ||
Libdl.dlclose(dl) | ||
end | ||
|
||
let dl = Libdl.dlopen_e("./libccalltest") | ||
@test dl != C_NULL | ||
Libdl.dlclose(dl) | ||
end | ||
|
||
let dl = Libdl.dlopen_e(join(("./libccalltest", string(".", Libdl.dlext)))) | ||
@test dl != C_NULL | ||
Libdl.dlclose(dl) | ||
end | ||
|
||
let dl = Libdl.dlopen_e("./foo") | ||
@test dl == C_NULL | ||
end | ||
|
||
# test dlpath | ||
let dl = Libdl.dlopen("./libccalltest") | ||
try | ||
@test dl != C_NULL | ||
@test Base.samefile(abspath(Libdl.dlpath(dl)), | ||
abspath(Libdl.dlpath("./libccalltest"))) | ||
@test Base.samefile(abspath(Libdl.dlpath(dl)), | ||
abspath(join(("./libccalltest",Libdl.dlext), '.'))) | ||
finally | ||
Libdl.dlclose(dl) | ||
end | ||
end | ||
|
||
# opening a library that does not exist throws an ErrorException | ||
@test_throws ErrorException Libdl.dlopen("./foo") | ||
|
||
# test dlsym | ||
let dl = Libdl.dlopen("./libccalltest") | ||
try | ||
fptr = Libdl.dlsym(dl, :set_verbose) | ||
@test fptr != C_NULL | ||
@test_throws ErrorException Libdl.dlsym(dl, :foo) | ||
|
||
fptr = Libdl.dlsym_e(dl, :set_verbose) | ||
@test fptr != C_NULL | ||
fptr = Libdl.dlsym_e(dl, :foo) | ||
@test fptr == C_NULL | ||
finally | ||
Libdl.dlclose(dl) | ||
end | ||
end |