Hello all!
I would like to understand, how the DLLs are loaded by the EXE generated with PackageCompiler.jl.
The issue is that I have a problem with a compiled program and the GR_jll.jl DLLs. Specifically, when exporting a plot as a file, I get the error GKS: svgplugin.dll: can't load library, error 126 (0x7e)
However, the very first EXE I compiled is working as expected and does not throw this error. Alas, I am unable to reproduce this working EXE. All further compiled EXE do not work and throw this error. Unfortunaltely I cannot test with the exact same Manifest.toml, as I deleted it and did not save it. I know the exact Julia and PackageCompiler version and the git commit of my project and the exact same Project.toml file. Using those information, though, I cannot reproduce a working binary program.
I was analyzing both EXE files with the Microsoft “Process Monitor” and figured out the following:
For the working EXE I get the following:
Operation | Path | Result |
---|---|---|
CreateFile, QueryBasicInformationFile, QueryNetworkOpenInformationFile, CloseFile (repeats several times, including other operations too) | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin\libGR.dll | SUCCESS |
" same | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin\libGR3.dll | SUCCESS |
" same | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin\libGRM.dll | SUCCESS |
" same | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin | SUCCESS |
" same | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\fonts\CMUSerif-Math.ttf | SUCCESS |
" same | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\fonts\DejaVuSans.ttf | SUCCESS |
CreateFile | C:\Users\user.julia\dev\Project\build-\bin\svgplugin.dll | NAME NOT FOUND |
CreateFile | Repeat this basically for a bunch of directories which seem to be in PATH | NAME NOT FOUND |
CreateFile, QueryBasicInformationFile, QueryNetworkOpenInformationFile, CloseFile (repeats several times, including other operations too) | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin\svgplugin.dll | SUCCESS |
What happens here? → The EXE searches for libGR.dll, libGR3.dll, libGRM.dll and two font *.ttf files directly in the artifact path and finds them. Then it searches for svgplugin.dll in, what seems to be PATH and does not find it there, only then it searches directly in the GR_jll artifact path (but not in other artifact pathes. Where does it know that it does need to search in artifacts/1533… and not in an other folder, and why does it search the PATH locations first? Anyways, in the end it works.
Now for the EXE that does not work. In the beginning, everything looks exactly the same. However, after the file svgplugin.dll could not be found in PATH, it just returns the error from above and does not try to look it up in the artifacts directory…:
Operation | Path | Result |
---|---|---|
… | all like above | … |
CreateFile | C:\Users\user.julia\dev\Project\build-\bin\svgplugin.dll | NAME NOT FOUND |
CreateFile | Repeat this basically for a bunch of directories which seem to be in PATH | NAME NOT FOUND |
ReadFile (several times) | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin\libGR.dll | SUCCESS |
Instead of finding and opening the svgplugin.dll, the libGR.dll is opened several times. (Maybe this is a fallback handle, but which actually doesn’t do anything, as the requested plots are not displayed)
When I look at the content of the folder artifacts\153311dc318ce37241d461f6c601d9bad6421624\bin\
, I see the following files:
aggplugin.dll, cairoplugin.dll, gksqt.exe, glplugin.dll, gr.js, grplot.exe, gsplugin.dll, gtkplugin.dll, libGKS.dll, libGR.dll, libGR3.dll, libGRM.dll, libqt6gr.dll, pgfplugin.dll, qt5plugin.dll, qt6plugin.dll, qtplugin.dll, svgplugin.dll, videoplugin.dll, wmfplugin.dll, x11plugin.dll, zmqplugin.dll
But when I look into the file src/wrappers/x86_64-w64-mingw32-cxx11.jl
from the packeg GR_jll.jl, I only find an @declare_library_product
(or declare_executeable_product) call for the ones marked in bold.
My Question
Now, writing all this together, I realize that svgplugin.dll might not be loaded by the EXE directly, but via the chain EXE → loads libGR.dll (or one of the other bold ones) → loads svgplugin.dll
But I would like to understand, why in case of one compiled binary, the lookup of svgplugin.dll works consistently (just cannot reproduce the another EXE that works the same, but executing this EXE works correct consistently), and for other compiled binaries that are generated with supposedly the same versions and parameters, svgplugin.dll cannto be found.
Does anybody have a clue for me why this may be and what I could do to get to the rootcause?
Background information:
I am running on Windows 10, 64 bit, Julia 1.10.9 (also tested 1.10.10, but this didn’t change anything) with PackageCompiler 2.2.1 and GR_jll is 0.72.10+0 (as GR is set to 0.72 in the Project.toml), and the GR_jll artifacts are stored under the hash artifacts/153311dc318ce37241d461f6c601d9bad6421624
Edit: My package compiler command looks like this:
create_app(PROJECT_FOLDER, BUILD_FOLDER; force=true,
executables=[PROGRAM_NAME=>"julia_main"],
include_lazy_artifacts=true)
Also, for both (the working and not working) EXE during startup, see the following operations in the Microsoft Process Monitor:
Operation | Path | Result |
---|---|---|
CreateFile | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624 | SUCCESS |
QueryAllInformationFile | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624 | BUFFER OVERFLOW |
QueryInformationVolume | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624 | BUFFER OVERFLOW |
QueryNetworkOpenInformationFile | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624 | SUCCESS |
CloseFile | C:\Users\user.julia\dev\Project\build-\share\julia\artifacts\153311dc318ce37241d461f6c601d9bad6421624 | SUCCESS |
So it seems, the artifact folder for the GR_jll DLLs is at least somewhat inspected uppon EXE Startup time. Not sure if this is relevant. But I wanted to point out that both EXE binaries are somewhat aware of this folder at least.
Many thanks for reading until here and many thanks for your comments, ideas and help!